본문 바로가기
Spring/study

스프링 프레임워크 입문 -AOP(Aspect Oriented Programming)

by avvin 2019. 5. 31.

스프링 프레임워크 입문 -AOP(Aspect Oriented Programming)



AOP : 흩어진 코드를 한 곳에 모아서 코딩하는 프로그래밍 기법


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
흩어진 AAAA 와 BBBB
 
class A {
 
    method a () {
        AAAA
        오늘은 7월 4일 미국 독립 기념일이래요.
        BBBB
    }
 
    method b () {
        AAAA
        저는 아침에 운동을 다녀와서 밥먹고 빨래를 했습니다.
        BBBB
    }
 
}
class B {
 
    method c() {
        AAAA    
        점심은 이거 찍느라 못먹었는데 저녁엔 제육볶음을 먹고 싶네요.
        BBBB
    }
 
}
 
cs




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 한 곳으로 모음

class A {
    method a () {    
        오늘은 7월 4일 미국 독립 기념일이래요.
    }
    method b () {
        저는 아침에 운동을 다녀와서 밥먹고 빨래를 했습니다.
    }
    
}
class B {
    method c() {
    점심은 이거 찍느라 못먹었는데 저녁엔 제육볶음을 먹고 싶네요.
    }
}
class AAAABBBB {
    
    method aaaabbb(JoinPoint point) {
    AAAA
    point.execute()
    BBBB
    }
}
cs

A와 B를 호출하는게 아니라 AAAABBB()에 매개값을 다르게 주어 호출하는 식인가?


=> single responsibility principle




AOP 적용 예제


@Transactional


트랜잭션 : 복수쿼리를 한 단위로 묶은 것. 한 덩어리의 퀴리 처리 단위?



트랜잭션 처리


AAAA를 transaction manager를 사용하여 transaction auto commit을 false로 만들고 작업 진행.

작업한 뒤에 트랜잭션 커밋

try-catch 블럭에서 진행되는데, 

문제가 생기면 catch 블럭 안에서 트랜잭션을 rollback(종료) 시킴


*Spring Data JPA 가 제공하는 모든 메서드에는 기본적으로 다 transactional이 적용돼있음


*Spring 데이터 JPA는 Java Persistence API (JPA)에 대한 저장소 지원을 제공합니다. 

JPA 데이터 소스에 액세스해야하는 응용 프로그램의 개발을 용이하게합니다.


출처 : https://translate.google.com/translate?hl=ko&sl=en&u=https://docs.spring.io/spring-data/jpa/docs/current/reference/html/&prev=search



스프링 bean만 Aspect가 될 수 있다.


logAspect는 스프링 bean



이 @Transactional과 같은 원리로 만든 예제 코드 


aspect 폴더에 LogExceptionTime 인터페이스 만들기 (어노테이션 만들기)


1
2
3
4
5
6
7
8
9
@Target(ElementType.METHOD)        
// LogExceptionTime 어노테이션을 적용할 타겟은 메서드 
@Retention(RetentionPolicy.RUNTIME) 
//LogExceptionTime 어노테이션에 사용될 코드를 언제까지 적용할건지 정해줌
//: 런타임동안 적용 유지
public @interface LogExecutionTime {
 
}
 
cs


어노테이션 자체에는 기능이 없다.


이렇게 만든 어노테이션을 처리해줄 실제 aspect 클래스가 필요


같은 aspect폴더에 logAspect 클래스 만들기


logAspect 클래스 (LogExceptionTime 어노테이션을 처리해줄 aspect 클래스)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component // aspect클래스는 스프링 bena이어야만 한다.
@Aspect
public class LogAspect {
 
    Logger logger = LoggerFactory.getLogger(LogAspect.class);
 
    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Object proceed = joinPoint.proceed();
        stopWatch.stop();
        logger.info(stopWatch.prettyPrint());
 
        return proceed;
    }
}
cs




위 트랜잭션 처리를 하는 @Transactional 어노테이션도 위 @LogExceptionTime과 같은 원리로 만들어짐

@Transactional을 처리하는 aspect 클래스에 트랜잭션 처리 코드가 있다.