Spring源码(13)--AOP 连接点及通知的方法调用的源码

AOP基础知识

AOP基础知识,详情见: https://blog.csdn.net/sinat_32502451/article/details/142291052

AOP 源码,详情见: https://blog.csdn.net/sinat_32502451/article/details/142291110

ProceedingJoinPoint

在上面的示例中,运用到了 ProceedingJoinPoint 。

ProceedingJoinPoint 是继承 JoinPoint(连接点) 的类。
从以上示例代码看出, ProceedingJoinPoint拥有 JoinPoint(连接点)的特性,
可以获取类的信息,包括类名、方法名、参数等(joinPoint.getArgs()),
还可以执行目标对象方法的逻辑(joinPoint.proceed())。

代码: org.aspectj.lang.ProceedingJoinPoint

/**
 *   ProceedingJoinPoint 继承 JoinPoint(连接点) .
 *   ProceedingJoinPoint 公开了progress(..)方法,以支持@AJ aspects.
 *
 */
public interface ProceedingJoinPoint extends JoinPoint {

    /**
     *  joinpoint需要知道它的AroundClosure,以便proceed可以委托给closure.run()
     * 
     */
    void set$AroundClosure(AroundClosure arc);

    /**
     * 继续下一个advice或目标方法调用
     *
     */
    public Object proceed() throws Throwable;

    /**
     * 继续下一个advice或目标方法调用
     *
     */
    public Object proceed(Object[] args) throws Throwable;

}

ReflectiveMethodInvocation的proceed

不管是 @Pointcut 还是 @Around(环绕通知,包含前置和后置两个) 都会调用这个 proceed 方法。

代码: org.springframework.aop.framework.ReflectiveMethodInvocation#proceed

    @Override
    @Nullable
    public Object proceed() throws Throwable {

        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
          //以下会调用 Joinpoint(连接点) 
          // 通过 invokeJoinpoint 的调用, 可以拿到目标方法的返回值。 
          
          //注意: 这里的 invokeJoinpoint() 调用的是 
          // org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation#invokeJoinpoint
          //并不是自身的 invokeJoinpoint()方法。
            return invokeJoinpoint();
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            }
            else {
                return proceed();
            }
        }
        else {
            // 拦截器调用方法。@Around 环绕通知的前置和后置都会走这里
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }

CglibAopProxy.CglibMethodInvocation

调用 joinPoint.proceed(); 这一行代码后,最后会调用这里的 Cglib 动态代理。

Cglib 动态代理,调用连接点的方法。

通过 invokeJoinpoint 的调用, 可以拿到目标方法的返回值。

代码: org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation#invokeJoinpoint

    private static class CglibMethodInvocation extends ReflectiveMethodInvocation {

        private final MethodProxy methodProxy;

        private final boolean publicMethod;

        public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
                Object[] arguments, @Nullable Class<?> targetClass,
                List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {

            super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
            this.methodProxy = methodProxy;
            this.publicMethod = Modifier.isPublic(method.getModifiers());
        }

        /**
         * 调用 JoinPoint(连接点) 的方法
         */
        @Override
        protected Object invokeJoinpoint() throws Throwable {
            if (this.publicMethod) {
                // 通过这里的调用, 可以拿到目标方法的返回值。
                return this.methodProxy.invoke(this.target, this.arguments);
            }
            else {
                return super.invokeJoinpoint();
            }
        }
    }

CglibAopProxy.DynamicAdvisedInterceptor

代码: org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor

调用 JoinPoint(连接点) 的方法后,会进行后置通知,调用 CglibAopProxy.DynamicAdvisedInterceptor。

    /**
     * 通用AOP回调。当目标是动态的或代理未冻结时使用。
     *
     */
    private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

        private final AdvisedSupport advised;

        public DynamicAdvisedInterceptor(AdvisedSupport advised) {
            this.advised = advised;
        }

        @Override
        @Nullable
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object oldProxy = null;
            boolean setProxyContext = false;
            Object target = null;
            TargetSource targetSource = this.advised.getTargetSource();
            try {
                if (this.advised.exposeProxy) {
                   
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }
                target = targetSource.getTarget();
                Class<?> targetClass = (target != null ? target.getClass() : null);
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                Object retVal;
                // 这里面的逻辑,重点看看。
                // 检查是否没有真正的advice,只是对目标的反射调用。
                if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                    // 我们可以跳过创建 MethodInvocation:直接调用目标。
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = methodProxy.invoke(target, argsToUse);
                }
                else {
                    // 创建一个方法调用。
                    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
                }
                retVal = processReturnType(proxy, target, method, retVal);
                return retVal;
            }
            finally {
                if (target != null && !targetSource.isStatic()) {
                    targetSource.releaseTarget(target);
                }
                if (setProxyContext) {
                    AopContext.setCurrentProxy(oldProxy);
                }
            }
        }

调用的方法栈:

这些代码也可以看看。

processReturnType:394, CglibAopProxy (org.springframework.aop.framework)
access$000:84, CglibAopProxy (org.springframework.aop.framework)
intercept:690, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
getValue:-1, TestController$$EnhancerBySpringCGLIB$$682df634 (com.example.demo.controller)
invoke:-1, GeneratedMethodAccessor68 (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:497, Method (java.lang.reflect)
doInvoke:209, InvocableHandlerMethod (org.springframework.web.method.support)
invokeForRequest:136, InvocableHandlerMethod (org.springframework.web.method.support)
invokeAndHandle:102, ServletInvocableHandlerMethod (org.springframework.web.servlet.mvc.method.annotation)
invokeHandlerMethod:891, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handleInternal:797, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handle:87, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
doDispatch:991, DispatcherServlet (org.springframework.web.servlet)
doService:925, DispatcherServlet (org.springframework.web.servlet)
processRequest:974, FrameworkServlet (org.springframework.web.servlet)
doGet:866, FrameworkServlet (org.springframework.web.servlet)
service:635, HttpServlet (javax.servlet.http)
service:851, FrameworkServlet (org.springframework.web.servlet)
service:742, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:52, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:99, RequestContextFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:109, HttpPutFormContentFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:93, HiddenHttpMethodFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:200, CharacterEncodingFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
invoke:198, StandardWrapperValve (org.apache.catalina.core)
invoke:96, StandardContextValve (org.apache.catalina.core)
invoke:493, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:140, StandardHostValve (org.apache.catalina.core)
invoke:81, ErrorReportValve (org.apache.catalina.valves)
invoke:87, StandardEngineValve (org.apache.catalina.core)
service:342, CoyoteAdapter (org.apache.catalina.connector)
service:800, Http11Processor (org.apache.coyote.http11)
process:66, AbstractProcessorLight (org.apache.coyote)
process:806, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1498, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:745, Thread (java.lang)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值