Spring: Aop before after Return after Throwing around 의 원리

이 글 을 쓰기 전에 인터넷 에서 대부분의 글 을 보 았 는데 이 부분 을 말 할 때 모두 언어 로 표현 했다.before, after, after Return, after Throwing 이라는 네 가지 언어 는 분명하게 말 할 수 있 지만, around 는 언어 로 는 어렵 습 니 다.
        여기 서 before, after, after Return, after Throwing, around 가 어떻게 실행 되 는 지 코드 로 보 여 드 리 겠 습 니 다.
 
Around 를 사용 하지 않 을 때 실현 은 다음 과 같이 이해 할 수 있 습 니 다.
public class XxxProxy implement InvocationHandler {
    private Target target;
    private Interceptor interceptor;

    public Object invoke(Object proxy, Method method, Object[] args) throws Exception{
        interceptor.before();
        boolean hasReturnValue = method.getReturnType!=void.class;
        try{
            Object result = null;
            if(hasReturnValue){
                result = method.invoke(target, args);
            }else{
                method.invoke(target, args);
            }
            interceptor.afterReturn();
            return result;            
        }catch(Exception ex){
            interceptor.afterThrowing();
            throw ex;
        }finally{
            interceptor.after();
        }
    }
}

 
Around 를 사용 할 때 이렇게 이해 할 수 있 습 니 다.
public class XxxProxy implement InvocationHandler {
    private Target target;
    private Interceptor interceptor;

    public Object invoke(Object proxy, Method method, Object[] args) throws Exception{
        interceptor.before();
        boolean hasReturnValue = method.getReturnType!=void.class;
        try{
            ProxyMethodInvocation methodInvocation = new ReflectiveMethodInvocation(proxy, method, target, args);
            ProceedingJoinPoint proceed = new MethodInvocationProceedingJoinPoint(target, parameters);
            Object result = null;
            //   Around            
            if(hasReturnValue){
                result = interceptor.around(proceed); //    around         proceed.procced(); 
            }else{
                interceptor.around(proceed);
            }
            interceptor.afterReturn();
            return result;            
        }catch(Exception ex){
            interceptor.afterThrowing();
            throw ex;
        }finally{
            interceptor.after();
        }
    }
}

public class ReflectiveMethodInvocation implements ProxyMethodInvocation {
    private Object proxy;
    private Object target;
    private Method method;
    private Object[] args;
    
    public ReflectiveMethodInvocation(Object proxy, Method method, Object target, Object[] args){
        this.proxy = proxy;
        this.method = method;
        this.target = target;
        this.args = args;
    }

    public Method getMethod(){
        return this.method;
    }
    public Object[] getArgs(){
        return args;
    }
    public Object[] getTarget(){
        return target;
    }

}

public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint{
    private ProxyMethodInvocation methodInvocation;
    public MethodInvocationProceedingJoinPoint(ProxyMethodInvocation methodInvocation){
        this.methodInvocation = methodInvocation;
    }

    public Object procced(){
        Object target = methodInvocation.getTarget();
        Object[] args = methodInvocation.getArgs();
        Method method = methodInvocation.getMethod();
        return method.invoke(target, args);
    }
}

좋은 웹페이지 즐겨찾기