Old Branch

Spring Framework Documentation - Spring AOP / Example -2

woolbro 2019. 6. 22. 18:10
반응형

이전포스팅입니다 :)

[Java/Spring-framework] - Spring Framework Documentation - Spring AOP / Example -1

 

Spring Framework Documentation - Spring AOP / Example -1

[Java/Spring-framework] - Spring Framework Documentation - IoC Container -2 Spring Framework Documentation - IoC Container -2 이전 포스팅입니다 [Java/Spring-framework] - Spring Framework Documentati..

woolbro.tistory.com

너무 길고 어려운 내용 들 이지만, Documents를 정리 하고 난 후 하나씩 구현 해볼 때가 기다려집니다...

하하ㅜㅜㅜ

 

오늘은, 이전포스팅에 이어서 AspectJ와 Pointcut 그리고 Advice를 보도록 하겠습니다. 자세한 사항들은 여기 Spring Documents를 참고 하시면 좋을 것 같아요 :) 

 


 

AOP Mechanism - @AspectJ 지원 활성화

원문을 참조하면

To use @AspectJ aspects in a Spring configuration, you need to enable Spring support for configuring Spring AOP based on @AspectJ aspects and auto-proxying beans based on whether or not they are advised by those aspects. By auto-proxying, we mean that, if Spring determines that a bean is advised by one or more aspects, it automatically generates a proxy for that bean to intercept method invocations and ensures that advice is executed as needed....
The @AspectJ support can be enabled with XML- or Java-style configuration. In either case, you also need to ensure that AspectJ’s aspectjweaver.jar library is on the classpath of your application (version 1.8 or later). This library is available in thelib directory of an AspectJ distribution or from the Maven Central repository.

 

proxy에 대한 내용또한 나오는데, auto-proxying이란 Spring이 aspect이 되었다고 판단하면, 그 메소드 호출을 보고 확인하기 위해서 bean에 대한 프록시를 자동으로 생성하고 필요에 따라 advice가 실행되도록 보장하는 것을 얘기합니다.

 

두가지로 나뉘게 됩니다. 위에서 공식문서에 나와있듯이 Java만으로 구성하기, XML 구성으로 활성화하기로 나뉘어집니다.  우선, Java구성으로 @AspectJ 지원 활성화입니다.

 

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
	//Somthing.....
}

 

XML구성으로 @AspectJ지원 활성화 입니다.

 

<!-- XML FILE...-->
<aop:aspectj-autoproxy/>

 

AOP Mechanism - @Pointcut 선언하기

pointcut은 관심있는 조인 포인트를 결정하므로, 실행 할 시기를 제어 할 수 있습니다.

pointcut 선언은 이름과 매개 변수로 구성 된  어노테이션 부분과, 관심있는 메소드 실행을 결정하는 pointcut 표현식 두 부분으로 구성이 됩니다. pointcut 어노테이션이 사용 된 메소드는 Void 리턴형을 가져야 합니다.

 

@Pointcut("execution(* transfer(..))")// the pointcut expression
private void anyOldTransfer() {}// the pointcut signature

 

pointcut 표현식에 관한 설명은 AspectJ Programming Guide에 있습니다. 보기 편하게... 제발 누군가 해석을 해주기를 바라며.....

 

 

대강 본 바로는 Pointcut 에서 사용하는 지정자는 execution, within, this, target, args 등이 있다고 합니다.... 각각의 지정자와 동일한 이름의 어노테이션도 존재하네요..

 

 

Pointcut 선언식은, AND 연산자(&&)와 OR 연산자(||)로 식을 합칠 수 있습니다.

 

@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {} //------------------------------1

@Pointcut("within(com.xyz.someapp.trading..*)")
private void inTrading() {} //---------------------------------------2

@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} //--------------------------------3

 

1: anyPublicOperation 메소드 실행 jointpoint가 public 메소드의 실행을 나타내는 경우...

 

2: inTrading  메소드 실행이 com.xyz.someapp.trading 모듈에 있다면..

 

3: tradingOperation 메소드 실행이 anyPublicOperation() 과 inTrading()모듈과 일치하는 경우..

 

 

아래는 선언식의 예 입니다...

//모든 public 메소드 실행
excution(public * * (..))

//set으로 시작하는 이름을 가진 메소드 실행
execution(* set*(..))

//AccountService 인터페이스에 의해 정의 된 모든 메서드 실행
execution(* com.xyz.service.AccountService.*(..))

//서비스 패키지 내의 모든 조인포인트
within(com.xyz.service.*)

//대상객체가 AccountService 인터페이스를 구현하는 모든 조인포인트
target(com.xyz.service.AccountService)

 

AOP Mechanism - Advice 선언하기
(Before, After Returning, After Throwing, After Finally, Around)

 

- before Advice : 실행되기 이전..

 

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeExample {

    @Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
    public void doAccessCheck() {
        // ...
    }

}
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeExample {

    @Before("execution(* com.xyz.myapp.dao.*.*(..))")
    public void doAccessCheck() {
        // ...
    }

}

 

 

- After Returning Advice : 실행 된 후

 

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class AfterReturningExample {

    @AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
    public void doAccessCheck() {
        // ...
    }

}
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class AfterReturningExample {

    @AfterReturning(
        pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
        returning="retVal")
    public void doAccessCheck(Object retVal) {
        // ...
    }

}

 

 

- After Throwing Advice : Throwing 이후

 

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class AfterThrowingExample {

    @AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
    public void doRecoveryActions() {
        // ...
    }

}
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class AfterThrowingExample {

    @AfterThrowing(
        pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
        throwing="ex")
    public void doRecoveryActions(DataAccessException ex) {
        // ...
    }

}

 

 

- After (Finally) Advice : 마친 후

 

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;

@Aspect
public class AfterFinallyExample {

    @After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
    public void doReleaseLock() {
        // ...
    }

}

 

 

- Around Advice : 실행되는 동안

 

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;

@Aspect
public class AroundExample {

    @Around("com.xyz.myapp.SystemArchitecture.businessService()")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        // start stopwatch
        Object retVal = pjp.proceed();
        // stop stopwatch
        return retVal;
    }

}

 

 

 

Advice의 내용이 조금 길었네요...! 다음 포스팅에서는 Introduction과 예제들을 살펴보도록 하겠습니다!!