본문 바로가기

Programing/Spring FrameWork

[Spring] AOP ( Aspect Oriented Programming )

728x90
반응형

[Spring] AOP ( Aspect Oriented Programming )


Spring AOP ( Aspect Oriented Programming )

 

  • 관점 지향 프로그래밍
  • 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 각각 모듈화하는 것
  • 흩어진 관심사 ( Crosscutting Concerns ): 소스 코드 상에서 다른 부분에 계속 반복해서 쓰는 코드들
  • 취지: 흩어진 관심사를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하는 것

-> 관점 지향 프로그래밍

-> 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나느어서 보고 그 관점을 각각 모듈화하겠다는 것


 

다양한 AOP 구현 방법

 

  • 컴파일   A.java -> (AOP) -> A.class ( AspectJ )
  • 바이트코드 조작   A.java -> A.class -> ( AOP ) -> 메모리 ( AspectJ ): 메모리에 올리는 시점에 바이트코드 조작 
  • 프록시 패턴 ( 스프링 AOP )

 

프록시 패턴 구현 예제

 

interface: Payment.java

class: Store.java, Cash.java, CashPerf.java

test: StoreText.java

 

Payment.java ( Interface )

public interface Payment {

	void pay(int amount);

}

 

Store.java

public class Store {

	Payment payment;

	public Store(Payment payment) {
		this.payment = payment;
	}

	public void buySomething(int amount){
		payment.pay(amount);
	}

}

 

Cash.java

public class Cash implements Payment {

	@Override
	public void pay(int amount) {
		System.out.println(amount +" 현금 결제");
	}

}

 

CashPerf.java

public class CashPerf implements Payment {

	Payment cash = new Cash();

	@Override
	public void pay(int amount) {

		// running time check
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();

		cash.pay(amount);

		stopWatch.stop();
		System.out.println(stopWatch.prettyPrint());

	}
}

 

StoreTest.java ( Test )

public class StoreTest {

	@Test
	public void testPay() {

		Payment cashPerf = new CashPerf();
		Store store = new Store(cashPerf);
		store.buySomething(100);

	}

}

 

결과


@LogExecutionTime 애노테이션으로 메소드 처리 시간 로깅하기

@Target(ElementType.METHOD) // 메서드에 사용 (어디에 사용할건지)
@Retention(RetentionPolicy.RUNTIME) // Runtime까지 유지 (언제까지 유지할 것인지)
public @interface LogExecutiomnTime{

}

 

실제 Aspect ( @LogExecutionTime 애노테이션 구현 )  = 위 예제의 CashPerf와 유사 ( Cash는 target )

@Component
@Aspect
public class LogAspect {

    Logger logger = LoggerFactory.getLogger( LogAspect.class );
    
    // @annotation(LogExecutionTime) 주위에
    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime( ProceedingJoinPoint joinPoint) throws Throwable {
    	
        // joinPoint: target( LogExecutionTime 애노테이션이 붙어있는 메서드 )
        
        StopWatch stopwatch = new StopWatch();
        stopWatch.start();
        
        Object proceed = joinPoint.proceed();
        
        stopWatch.stop();
        logger.info(stopWatch.prettyPrint());
        
        return proceed;
        }
  
 }

 

 

728x90
반응형