웹/spring

[spring] AOP (Aspect Oriented Programming)

은은하게미친자 2022. 8. 25. 11:26
728x90

AOP (Aspect Oriented Programming)


: 관점 지향 프로그래밍, 어떤 로직을 기준으로 핵심적인/부가적인 관점을 나누어서 보고 그  관점을 기준으로 각각 모듈화 하는 것.

주로 로깅, 트랜잭션 관리, 에러처리 등 비즈니스단의 메소드를 조금더 세밀하게 조정하고싶을때 사용.

 

AOP는 핵심 모듈 사이에 필욯나 기능을 삽입하여 적절한 타이밍에 호출 되도록 해주는 기능.

이를 구현할때 스프링은 대상 빈을 프록시로 감싸는 방법을 사용합니다.

 

프록시?

어떠한 빈 (클래스)가 AOP대상이면 원본 클래스 대신 프록시가 감싸진 클래스가 자동으로 만들어져 프록시 클래스가 빈에 등록이 도비니다. 이렇게 빈에 등록된 프록시 클래스는 원본 클래스가 호출되면서 자동으로 바꿔서 사용해줍니다.

 

주요 개념

  • Aspect : 흩어진 관심사(Crosscutting Concerns), 즉핵심업무를 모듈화한것
  • Target : Aspect를 적용하는 곳 (클랫, 메서드)
  • Advice : 어떤일을 해야 할 지에 대한것, 실직적인 부가 기능을 담은 구현체
  • JoinPoint : Advice가 적용될 위치 ex ) 끼어들수있는 지점, 메서드 진입지점, 생성자 호출 지점 등
  • PointCut : JointPoint의 상세한 스펙을 정의한것, 구체적인 Advice 실행지점을 정할 수있음.
  • Weaving : AOP에서 joinpoint들을 advice로 감싸는 과정이다. 이작업을 도와주는것이 AspectJ등의 AOP툴이 하는 역할이다.

AOP 주요 애너테이션 및 포인트컷

@Component 스프링 context에 빈으로등록 , <Bean class=“…”/> 와 같은표현
@Aspect @Aspect 임을 명시
@Around("${pattern}") 지정된 패턴에 해당하는 메소드의 실행 전/후에 동작
지정된 메소드의 반환값:  Object (지정된 패턴에 해당하는 메소드의 실행 결과를 반환해야 하므로)
pointcut 표현식의 패턴이 들어간다.

ex))  @Around("execution(* kr.co.dong.controller.*Controller.*(..))")
@Before("${pattern}") 지정한 패턴에 해당하는 메소드가 실행 되기전에 , interceptor와 같이 동작
지정된 메소드의 반환값 : void
@After("${pattern}") 지정한 패턴에 해당하는 메소드가 실행된 후에 동작
지정된 메소드의 반환값 : void
@AfterReturning() 해당하는 메소드가 정상적인 수행 후
@AfterThrowing() 예외발생후

+ Pointcut 표현식

  • *  :  ALL
  • (..) : 0개이상
  • *Controller.*(..)  : 모든 컨트롤러 하위에 있는 모든 메서드 중 인자가 0개이상인 모든것.

 

적용해보기

 

1. pom.xml에  aspectj 셋업 확인하기

aspectj 버전확인하기 <org.aspectj-version>1.8.9</org.aspectj-version>
aspectjweaver 추가
1
2
3
4
5
6
7
8
      <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
      <dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjweaver</artifactId>
         <version>1.9.9.1</version>
         <scope>runtime</scope>
      </dependency>
 
cs

 
maven update 하기

 

2. servlet-context.xml   

aop, tx 설정 체크하고 저장하기

aspectj
자동 프록시 
태그 추가하기
1
2
    <!-- AOP 실행을 위해 컴포넌트 등록 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
cs

3. 구현

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
package kr.co.dong.commom;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
 
@Component //스프링 context에 빈으로등록
@Aspect    //@Aspect 명시
public class LoggerAspect {
    protected Logger log = LoggerFactory.getLogger(LoggerAspect.class);
    
    @Around("execution(* kr.co.dong.controller.*Controller.*(..))")
    public Object logPrint(ProceedingJoinPoint joinpoint) throws Throwable {
        Object result = null;
        
        long start = System.currentTimeMillis(); 
 
        result = joinpoint.proceed();
        
        long end = System.currentTimeMillis(); 
        
        log.info(String.format("수행시간 : %dms %n", (end-start)));
        return result;
    }
    
}
 
cs

 

4. 정상처리시

728x90