티스토리 뷰

Skill/spring

[spring boot] AOP 설정

진열사랑 2021. 2. 24. 17:45

출처 : jeong-pro.tistory.com/171

 

Spring AOP (Aspect Oriented Programming)

- AOP는 관점 지향 프로그래밍으로 "기능을 핵심 비즈니스 기능과 공통 기능으로 '구분'하고, 공통 기능을 개발자의 코드 밖에서 필요한 시점에 적용하는 프로그래밍 방법"이다.

 

AOP 적용하는 법 3단계

1. spring-boot-starter-aop dependency 적용하기

라이브러리는 있어야지.

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-aop</artifactId>

</dependency>

2. @EnableAspectJAutoProxy 적용하기

최상위 패키지에 있는 클래스에 Annotation을 적용해서 AOP를 찾을 수 있게 해준다.

@EnableAspectJAutoProxy

@SpringBootApplication

public class AoploggingApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(AoploggingApplication.class, args);

    }

}

3. 공통기능을 정의하고 공통기능이 사용될 시점을 정의한다.

@Aspect

@Component

public class LogAspect {

    Logger logger =  LoggerFactory.getLogger(LogAspect.class);

    

    //BookService의 모든 메서드

    @Around("execution(* com.example.demo.service.BookService.*(..))")

    public Object logging(ProceedingJoinPoint pjp) throws Throwable {

        logger.info("start - " + pjp.getSignature().getDeclaringTypeName() + " / " + pjp.getSignature().getName());

        Object result = pjp.proceed();

        logger.info("finished - " + pjp.getSignature().getDeclaringTypeName() + " / " + pjp.getSignature().getName());

        return result;

    }

}

 

@Around는 메서드의 실행 전/후에 공통로직을 적용하고 싶을 때 사용하고 @Before는 메서드 실행 전에, @After는 메서드 실행 후에 공통 로직을 적용하고 싶을 때 사용한다.

즉 어느 시점에 적용할 것인지를 정의하는 것이다.

 

AOP 적용 시점 pointcut 표현식

@Around("execution(* com.example.demo.service.BookService.*(..))") 를 통해서 어떤 메서드들이 이 AOP를 적용받을 것인지를 정의했다.

execution(* com.example.demo.service.BookService.*(..))는 com.example.demo.service 패키지의 BookService의 모든 메서드가 적용받을 것이라고 한 것이다. (pointcut 표현식)

다양한 표현식을 이용해서 원하는 부분에만 적용할 수 있을 것이다.

다른 블로그에서 인용(?)해온 표현식들을 보고 알맞게 적용할 수 있도록 하자.

 Pointcut

JoinPoints 

 execution(public * *(..))

 public 메소드 실행

 execution(* set*(..))

 이름이 set으로 시작하는 모든 메소드명 실행

 execution(* get*(..))

 이름이 get으로 시작하는 모든 메소드명 실행

 execution(* com.xyz.service.AccountService.*(..))

 AccountService 인터페이스의 모든 메소드 실행

 execution(* com.xyz.service.*.*(..))

 service 패키지의 모든 메소드 실행

 execution(* com.xyz.service..*.*(..))

 service 패키지와 하위 패키지의 모든 메소드 실행

 within(com.xyz.service.*)

 service 패키지 내의 모든 결합점 (클래스 포함)

 within(com.xyz.service..*)

 service 패키지 및 하위 패키지의 모든 결합점 (클래스 포함)

 bean(*Repository)

 이름이 “Repository”로 끝나는 모든 빈

 bean(*) 모든 빈
 bean(account*) 이름이 'account'로 시작되는 모든 빈

 bean(*dataSource) || bean(*DataSource)

 이름이 “dataSource” 나 “DataSource” 으로 끝나는 모든 빈

출처 : http://devjms.tistory.com/70

공통으로 사용될 메서드를 보도록 하자.

여기서는 Object를 리턴하도록 되어있는데 아주 중요하다.

왜냐하면 AOP는 메서드를 가로채서(Proxy) 앞이나 뒤에 필요한 공통로직을 한다고 했기 때문이다.

즉 proceed()에서 정상적으로 메서드를 실행한 후 리턴 값을 주는데 가로채서 어떤 action을 한 후에 기존 리턴 값을 되돌려 주지 않으면 가로챈 AOP가 결과값을 변경한 것, 지워버린 것과 다름없다.

위 메서드에서는 단순하게 앞/뒤로 추가 로깅을 찍어주고 기존 메서드가 실행될 수 있게 pjp.proceed();를 호출했다.

 

 #AOP설정, #spring

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함