장쫄깃 기술블로그

[Spring Boot] AOP 설정 본문

Spring Framework/Spring Boot

[Spring Boot] AOP 설정

장쫄깃 2022. 4. 15. 17:18
728x90


AOP에 대한 설명은 해당 글을 참고

링크 : https://jangjjolkit.tistory.com/6

 

[Spring Boot] Filter, Interceptor, AOP

들어가며 자바 웹 개발을 하다보면, 공통적으로 처리해야할 업무들이 많다. 예를들어 로그인, 권한, XSS, pc/mobile 등 사용자 agent 체크, 로그, 페이지 인코딩 변환 등이 있다. 공통업무에 관련된 코

jangjjolkit.tistory.com

AOP 상세 설명 참고

링크 : https://jangjjolkit.tistory.com/10

 

[Spring Boot] AOP(Aspect Oriented Programming) 란?

들어가며 이전 글들에서 AOP에 대해 설명한 적이 있다. 그런데 AOP가 파면 팔수록 알아야 할 부분이 많다고 느꼈다. 그래서 별도로 AOP에 대한 세부적인 사항들에 대해 다뤄보려 한다. AOP(Aspect Orient

jangjjolkit.tistory.com


AOP 설정


@Component@Aspect 어노테이션을 적용한 클래스를 생성한다. 내부 메소드는 @Around 어노테이션을 사용하여 호출을 제어한다.

@Aspect
@Component
public class SomeAspect {
	@Around("execution(* com.some..controller..*Controller.*(..))")
	public Object some(ProceedingJoinPoint pjp) throws Throwable {
		// ...
	}
}
  • @Component
    • 스프링 컨테이너에 빈(Bean)으로 등록하기 위한 어노테이션
    • @Bean은 개발자가 제어할 수 없는 외부 라이브러리를 빈(Bean)으로 등록 시 사용하고, @Component는 개발자가 직접 정의한 클래스를 빈(Bean)으로 등록할 때 사용
  • @Aspect
    • AOP 기능을 하는 클래스의 클래스 레벨에 지정하는 어노테이션
  • @Around
    • 어드바이스의 종류 중 한 가지로 어드바이스는 총 5개 타입이 있음
    • 그중 Around는 메소드의 호출 자체를 제어할 수 있기 때문에 어드바이스 중 가장 강력한 기능이라고 볼 수 있음

 

 

AOP Advice(어드바이스)


본문을 읽기 전 AOP 용어를 참고하면 좋다.

링크 : https://jangjjolkit.tistory.com/11

 

[Spring Boot] AOP 용어

Advice 언제 공통 관심 기능을 핵심 로직에 적용할 지를 정의하고 있다. 예를 들어, '메서드를 호출하기 전'(언제)에 '트랜잭션을 시작한다.'(공통기능)기능을 적용한다는 것을 정의하고 있다. Targe

jangjjolkit.tistory.com

 

Advice(어드바이스) 동작 시점(JoinPoint)에 삽입되어 횡단 관심에 해당하는 공통 기능의 코드를 의미하며, 독립된 클래스의 메소드로 작성된다.

 

간단하게 말해, 어떤 동작 시점에 실행될 공통 기능을 구현한 모듈이다.

 

스프링에는 5개의 동작 시점이 제공된다.

  • @Before: 비즈니스 메소드 실행 전 동작
  • @AfterReturning: 비즈니스 메소드가 성공적으로 리턴되면 동작
    • 단, 메소드 내부 리턴값이 존재하는 경우)
  • @AfterThrowing: 비즈니스 메소드 실행 중, 예외가 발생하면 동작
    • 예를 들어, try ~ catch 중 catch 블록에 해당
  • @After: 비즈니스 메소드가 실행된 후 무조건 실행
  • @Around: 메소드 호출 자체를 가로채서 비즈니스 메소드 실행 전&후 모두에 처리할 로직을 삽입할 수 있음

 

 

PointCut


위 예시코드를 보면 @Around 안에 execution 이라고 하는 명시자를 볼 수 있다. 이는 실제로 Advice가 적용되는 JoinPoint인 PointCut을 명시한 것이다.

 

PointCut에는 execution, within, bean이 있다.

 

1. execution

접근 제어자, 리턴 타입, 타입 패턴, 메소드, 파라미터 타입, 예외 타입 등을 조합해서 정교한 포인트컷을 만들 수 있다.

예시 설명
execution(BoardDTO select*(..)) 리턴 타입이 BoardDTO 클래스이고,

메소드의 이름이 select로 시작하며,

파라미터가 0개 이상인 모든 메소드가 호출될 때

(0개 이상은 패키지, 메소드, 파라미터 등 모든 것을 의미)
execution(* com.board.controller.*()) 해당 패키지 밑에 파라미터가 없는 모든 메소드가 호출될 때
execution(* com.board.controller.*(..)) 해당 패키지 밑에 파라미터가 0개 이상인 모든 메소드가 호출될 때
execution(* com.board..select(*)) com.board 패키지의 모든 하위 패키지에 존재하는

select로 시작하고, 파라미터가 한 개인 모든 메소드가 호출될 때
execution(* com.board..select(*, *)) com.board 패키지의 모든 하위 패키지에 존재하는

select로 시작하고, 파라미터가 두 개인 모든 메소드가 호출될 때
execution(* com.board..controller.*Controller.*(..)) com.board 패키지의 모든 하위 패키지 중

controller로 시작하는 패키지에서

xxxController와 같은 패턴의 이름을 가진 클래스에서

파라미터가 0개 이상인 메소드를 의미
execution(* com.board..service.*Impl.*(..)) com.board 패키지의 모든 하위 패키지 중

service로 시작하는 패키지에서

xxxServceImpl과 같은 패턴의 이름을 가진 클래스에서

파라미터가 0개 이상인 메소드를 의미
execution(* com.board..mapper.*Mapper.*(..)) com.board 패키지에서 모든 하위 패키지 중

mapper로 시작하는 패키지에서

xxxMapper와 같은 패턴의 이름을 가진 인터페이스에서

파라미터가 0개 이상인 메소드를 의미

 

2. within

명시된 객체 내부에 있는 모든 메소드를 포인트컷으로 한다.

예시 설명
within(com.board.service.SomeService) com.board.service.SomeService 의 모든 메소드
within(com.board.service.*) com.board.service 패키지의 모든 메소드
within(com.board.service..*) com.board.service 패키지 및 하위 패키지의 모든 메소드

 

3. bean

명시된 빈의 모든 메소드를 포인트컷으로 한다.

예시 설명
bean(someBean) 이름이 someBean인 빈의 모든 메소드
bean(some*) 이름이 some 으로 시작하는 빈의 모든 메소드

 

* etc. @annotation, @within

특정 어노테이션이 설정된 모든 메소드를 포인트컷으로 한다.

예시 설명
@annotation(someAnnotation) someAnnotation 이 명시된 모든 메소드
@within(org.springframework.web.bind.annotation.RestController) 클래스 레벨에 특정 어노테이션이 명시된 모든 메소드

 

* 포인트컷 표현식은 and(&&) 또는 or(||)를 조합해서 사용할 수 있다.

ex) @Around(execution(BoardDTO select*(..)) && execution(* com.board.controller.*()))

 

 

ProceedingJoinPoint and ETC


ProceedingJoinPoint 인터페이스가 상속받는 클래스는 다음의 메소드를 포함한다.

메서드 설명
Object[] getArgs() 전달되는 모든 파라미터들을 Object 타입의 배열로 가지고 온다.
String getKind() 해당 어드바이스(Advice)의 타입을 가지고 온다.
Signature getSignature() 실행되는 대상 객체의 메서드에 대한 정보를 가지고 온다.
Object getTarget() 타겟(Target) 객체를 가지고 온다.
Object getThis() 어드바이스(Advice)를 행하는 객체를 가지고 온다.
728x90