본문 바로가기
Spring

[Spring/스프링] AOP @Aspect 사용법

by LasBe 2022. 4. 12.
반응형
 

[Spring/스프링] 관점 지향 프로그래밍(AOP)과 용어정리, Advice 종류

⚡️관점 지향 프로그래밍(Aspect Oriented Programming, AOP) 스프링의 핵심기능인 IoC가 객체들의 결합도를 느슨하게 만들어 의존 관계를 쉽게 변경한다면 AOP는 반복되는 기능을 독립적으로 분리해, 재

lasbe.tistory.com

Aspect 사용법을 알아보기 앞서 AOP에 대한 사전지식이 필요하신 분들은 위 글을 참고해주세요.

 

 

 

⚡️AOP 어노테이션 사용법


자바 스프링에서 AOP를 사용하기 위해선 2가지 방법이 존재합니다.

 

XML과 어노테이션을 이용하는 방법이 있는데, 이 글에서는 어노테이션을 이용한 방법을 다뤄볼 겁니다.

 

기본적인 내용들을 설명 후 AOP를 직접 사용해보겠습니다.

 


📌 pom.xml 사전 설정

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.0</version>
</dependency>

AOP를 이용하기 전 pom.xml의 dependencies에 위 코드를 추가해서,

AspectJ Weaver 라이브러리를 추가해주도록 합니다.


📌 Pointcut 어노테이션

 

[Spring/스프링] AOP의 포인트컷(Pointcut) execution() 표현식 사용법

⚡️포인트컷(Pointcut) 포인트컷이란 수많은 비즈니스 메소드 중에서 원하는 특정 메소드에게만 횡단 관심에 해당하는 공통 기능을 수행시키기 위해 클래스와 패키지, 메소드 시그니처를 이용해

lasbe.tistory.com

포인트 컷에 대한 자세한 내용은 위 글에서 소개했으니 참고 바랍니다.


📌 Advice 어노테이션

어노테이션 설명
@Before 메소드가 실행되기 이전에 실행됩니다.
@After 메소드의 종료 후 무조건 실행됩니다. (try-catch에서 finally와 같은 동작)
@After-returning 메소드가 성공적으로 완료되고 리턴한 다음에 실행됩니다.
@After-throwing 메소드 실행 중 예외가 발생하면 실행됩니다. (try-catch에서 catch와 같은 동작)
@Around 메소드 호출 자체를 가로채서 메소드 실행 전후에 처리할 로직을 삽입할 수 있습니다.

 

Advise의 종류와 사용법은 위와 같이 5가지가 존재합니다.

 

이를 사용하기 위해선 Pointcut 표현식으로 적용 범위를 적용해주어야 하는데,

대표적으로 다음과 같이 3가지 방식으로 Advice 어노테이션에 Pointcut을 적용 가능합니다.

 

@Component
@Aspect
public class SpringAspect {
	// -1-
	@Before("execution(* aop *.*(..)")
	public void aop1() {}
	
	// -2-
	private final String pointcut = "execution(* aop *.*(..)";
	@Before(pointcut)
	public void aop2() {}
	
	// -3-
	@Pointcut("execution(* aop *.*(..)")
	private void method() {} 
	
	@Before("method()")
	public void aop3() {}
}

 

 

 

⚡️AOP 사용 예제


AOP 사용 예제 주제로 메소드 실행 시 실행 시간을 측정하는 기능을 준비해봤습니다.

 

실행 시간을 측정하기 위해선 메소드 실행 전과 실행 후를 하나의 변수에 담아 측정해야하기 때문에

@Around Advice를 사용했습니다.

 

아래는 문자열을 파라미터로 받는 searchMember 메소드입니다.

 

데이터베이스에서 1초만큼 작업 시간이 소요된다고 가정하고 1초의 지연시간을 주었습니다.

@Repository
public class MemberDao {
	public void searchMember(String id) throws InterruptedException {
		System.out.println("searchMember 실행");
        
		Thread.sleep(1000); // 1초 정지
        
		System.out.println("searchMember 종료");
	}
}

 

이 searchMember 메소드의 시간을 구하기 위해 아래와 같은 Aspect를 사용했습니다.

@Component
@Aspect
public class SpringAspect {
	@Around("execution(* aop_obj.*.*(..))")
	public void timer(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("[Around] 시작");
		StopWatch sw = new StopWatch();
		
		sw.start();
		joinPoint.proceed(); // 메소드 시작
		sw.stop();
		
		System.out.println("[Around] 메소드 이름 : "+joinPoint.getSignature().getName());
		System.out.println("[Around] 메소드 첫번째 파라미터 : "+joinPoint.getArgs()[0]);
		System.out.println("[Around] 메소드 소요 시간 : "+sw.getTotalTimeMillis());
	}
}

@Around("execution(* aop_obj.*.*(..))")

포인트컷 표현식으로 MemberDao 클래스의 memberSearch 메소드를 포함 범위에 추가시켰습니다.

 

 

Around 어드바이스는 ProceedingJoinPoint를 파라미터로 받아

실행할 메소드의 시점을 조절하거나, 각종 정보들을 받아올 수 있습니다.

 

스톱워치를 시작하고 joinPoint.proceed()를 통해 가로챈 메소드를 실행시킨 후

메소드가 종료되면 스톱워치를 종료시켜 실행시간을 측정합니다.

 

그 후 메소드의 정보들과 측정한 시간을 출력합니다.

 

그럼 memberSearch 메소드를 실행시켜 AOP가 적용되는지 확인해보겠습니다.

 

public class Main {
	public static void main(String[] args) throws InterruptedException {
		ApplicationContext factory =
				new AnnotationConfigApplicationContext(ConfigClass.class);
		
		MemberDao md = factory.getBean("memberDao", MemberDao.class);
		
		md.searchMember("LasBe");
	}
}

컨테이너에서 빈을 받아와 searchMember 메소드를 실행시켜봤습니다.

 

메소드 전, 후로 Around 어드바이스가 잘 적용되어 출력된 것을 확인할 수 있습니다.

반응형

댓글


오픈 채팅