1、AOP动态代理的字节码文件
1.1、代理对象class的核心伪代码
1 public class MathCalculator$$EnhancerBySpringCGLIB$$9bfe5203 extends MathCalculator implements SpringProxy, Advised, Factory { 2 // 代理对象的属性是否已被绑定 3 private boolean CGLIB$BOUND; 4 public static Object CGLIB$FACTORY_DATA; 5 // 线程变量,用来存储callbacks集合 6 private static final ThreadLocal CGLIB$THREAD_CALLBACKS; 7 private static final Callback[] CGLIB$STATIC_CALLBACKS; 8 private MethodInterceptor CGLIB$CALLBACK_0; 9 private MethodInterceptor CGLIB$CALLBACK_1; 10 private NoOp CGLIB$CALLBACK_2; 11 private Dispatcher CGLIB$CALLBACK_3; 12 private Dispatcher CGLIB$CALLBACK_4; 13 private MethodInterceptor CGLIB$CALLBACK_5; 14 private MethodInterceptor CGLIB$CALLBACK_6; 15 16 //********** 1、静态代码块中执行CGLIB$STATICHOOK1(),并新建线程变量CGLIB$THREAD_CALLBACKS *******// 17 static { 18 CGLIB$STATICHOOK1(); 19 } 20 static void CGLIB$STATICHOOK1() { 21 // 创建线程变量,用来存储callbacks 22 CGLIB$THREAD_CALLBACKS = new ThreadLocal(); 23 // 被代理类的动态代理对象的 Class 24 Class var0 = Class.forName("com.snails.aop.xml.service.MathCalculator$$EnhancerBySpringCGLIB$$9bfe5203"); 25 Class var1; 26 var10000 = ReflectUtils.findMethods(new String[]{"add", "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;", "toString", "()Ljava/lang/String;"}, (var1 = Class.forName("com.snails.aop.xml.service.MathCalculator")).getDeclaredMethods()); 27 CGLIB$add$0$Method = var10000[0]; 28 29 // 创建代理类 30 CGLIB$add$0$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;", "add", "CGLIB$add$0"); 31 } 32 33 //***************************** 2、实例化代理对象,并填充代理对象的属性 ***************************// 34 public Object newInstance(Callback[] var1) { 35 // 初始化线程变量CGLIB$THREAD_CALLBACKS 36 CGLIB$SET_THREAD_CALLBACKS(var1); 37 // 构造函数,将线程变量里的Callback[]元素赋值给代理对象的属性(CGLIB$CALLBACK_0 - CGLIB$CALLBACK_7) 38 MathCalculator$$EnhancerBySpringCGLIB$$9bfe5203 var10000 = new MathCalculator$$EnhancerBySpringCGLIB$$9bfe5203(); 39 // 线程变量中的内容置空 40 CGLIB$SET_THREAD_CALLBACKS((Callback[])null); 41 // 返回创建代理对象 42 return var10000; 43 } 44 // 将Callback[]放入线程变量CGLIB$THREAD_CALLBACKS中 45 public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) { 46 CGLIB$THREAD_CALLBACKS.set(var0); 47 } 48 // 构造函数,填充代理对象的属性 49 public MathCalculator$$EnhancerBySpringCGLIB$$9bfe5203() { 50 CGLIB$BIND_CALLBACKS(this); 51 } 52 // 填充代理对象的属性 53 private static final void CGLIB$BIND_CALLBACKS(Object var0) { 54 MathCalculator$$EnhancerBySpringCGLIB$$9bfe5203 var1 = (MathCalculator$$EnhancerBySpringCGLIB$$9bfe5203)var0; 55 if (!var1.CGLIB$BOUND) { 56 var1.CGLIB$BOUND = true; 57 // 构造函数中,获取代理对象线程变量中的Callback[]集合 58 Object var10000 = CGLIB$THREAD_CALLBACKS.get(); 59 if (var10000 == null) { 60 var10000 = CGLIB$STATIC_CALLBACKS; 61 if (var10000 == null) { 62 return; 63 } 64 } 65 66 // 属性赋值 67 Callback[] var10001 = (Callback[])var10000; 68 var1.CGLIB$CALLBACK_6 = (MethodInterceptor)((Callback[])var10000)[6]; 69 var1.CGLIB$CALLBACK_5 = (MethodInterceptor)var10001[5]; 70 var1.CGLIB$CALLBACK_4 = (Dispatcher)var10001[4]; 71 var1.CGLIB$CALLBACK_3 = (Dispatcher)var10001[3]; 72 var1.CGLIB$CALLBACK_2 = (NoOp)var10001[2]; 73 var1.CGLIB$CALLBACK_1 = (MethodInterceptor)var10001[1]; 74 var1.CGLIB$CALLBACK_0 = (MethodInterceptor)var10001[0]; 75 } 76 } 77 78 //***************************** 3、执行切入点方法add ***************************// 79 public final Integer add(Integer var1, Integer var2) throws NoSuchMethodException { 80 // 获取CGLIB$CALLBACK_0属性 ,即获取Callback[]数组,位置为0的对象 81 MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; 82 // 若代理对象属性未填充 83 if (var10000 == null) { 84 // 将Callbacks集合中的元素绑定到代理对象的属性中 85 CGLIB$BIND_CALLBACKS(this); 86 // 获取CGLIB$CALLBACK_0属性,即获取Callback[]数组,位置为0的对象 87 var10000 = this.CGLIB$CALLBACK_0; 88 } 89 90 // 执行CALLBACK_0的intercept方法 91 return var10000 != null ? (Integer)var10000.intercept(this, CGLIB$add$0$Method, new Object[]{var1, var2}, CGLIB$add$0$Proxy) : super.add(var1, var2); 92 } 93 94 // 设置callback回调详情 95 public void setCallbacks(Callback[] var1) { 96 this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0]; 97 this.CGLIB$CALLBACK_1 = (MethodInterceptor)var1[1]; 98 this.CGLIB$CALLBACK_2 = (NoOp)var1[2]; 99 this.CGLIB$CALLBACK_3 = (Dispatcher)var1[3]; 100 this.CGLIB$CALLBACK_4 = (Dispatcher)var1[4]; 101 this.CGLIB$CALLBACK_5 = (MethodInterceptor)var1[5]; 102 this.CGLIB$CALLBACK_6 = (MethodInterceptor)var1[6]; 103 } 104 105 // 获取Callbacks集合 106 public Callback[] getCallbacks() { 107 CGLIB$BIND_CALLBACKS(this); 108 return new Callback[]{this.CGLIB$CALLBACK_0, this.CGLIB$CALLBACK_1, this.CGLIB$CALLBACK_2, this.CGLIB$CALLBACK_3, this.CGLIB$CALLBACK_4, this.CGLIB$CALLBACK_5, this.CGLIB$CALLBACK_6}; 109 } 110 111 }
1.2、代理对象class的执行流程图
代理对象的字节码伪代码可用如下流程图概括通过代理对象class的伪代码可以带出问题:
1、Callback[] 是什么,在哪里做的初始化 2、代理对象this.CGLIB$CALLBACK_0 指的是哪个对象? AbstractAutoProxyCreator#wrapIfNecessary->AbstractAutoProxyCreator#createProxy-> ProxyFactory#getProxy->CglibAopProxy#getProxy->CglibAopProxy#getCallbacks2、Callback[]详情
常用动态代理:JDK动态代理、CGLIB动态代理。CGLIB动态代理需要设置Callback的信息做回调,要弄清楚Callback[]的详情,还需要对代理对象的创建过程做进一步的分析,在AOP源码(三):创建AOP相关的bean中,分析出被代理类的代理对象是在初始化的后置处理节点创建的,并找到创建被代理类代理对象的入口AbstractAutoProxyCreator#wrapIfNecessary中的createProxy方法。2.1、创建代理对象的准备工作
2.1.1、创建代理对象准备工作
AbstractAutoProxyCreator#createProxy 核心伪代码:1 // 创建代理对象的准备工作 2 protected Object createProxy(Class<?> beanClass, @Nullable String beanName, 3 @Nullable Object[] specificInterceptors, TargetSource targetSource) { 4 // 创建代理工厂 5 ProxyFactory proxyFactory = new ProxyFactory(); 6 7 //================================ 1、获取创建动态代理的方式 ================================ // 8 // 使用CGLIB动态代理, 判断beanName对应的beanDefinition中的attribute 的 preserveTargetClass 是否为true,不设置默认为空 9 if (shouldProxyTargetClass(beanClass, beanName)) { 10 proxyFactory.setProxyTargetClass(true); 11 } 12 // 使用代理接口 jdk动态代理 13 else { 14 // 判断采用何种方式创建代理对象,被代理类实现了接口。将实现的接口设置进代理工厂中;未实现接口,将ProxyTargetClass标识设置为true 15 evaluateProxyInterfaces(beanClass, proxyFactory); 16 } 17 18 //================================ 2、封装ExposeInvovationInterceptor为Advisor ================================ // 19 // 构建Advisor, 此处主要是将ExposeInvovationInterceptor封装成Advisor对象,ExposeInvovationInterceptor相当于是责任链模式的控制器 20 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); 21 proxyFactory.addAdvisors(advisors); 22 23 // 实际创建代理对象 24 return proxyFactory.getProxy(getProxyClassLoader()); 25 }
1、获取创建代理对象的方式
获取创建动态代理创建方式的准备工作,为ProxyConfig的属性interfaces、proxyTargetClass赋值,用于后续的判断处理。 ProxyProcessorSupport#evaluateProxyInterfaces 核心代理如下:1 protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) { 2 // 获取所有被代理类的实现的接口 3 Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader()); 4 // 被代理类是否实现接口标识,默认为false 5 boolean hasReasonableProxyInterface = false; 6 // 若被代理类实现了有效的接口,将标识设置为true 7 for (Class<?> ifc : targetInterfaces) { 8 // IO容器的回调接口、内部引用依赖的接口不能作为有效的代理接口,需排除;被代理类实现的接口中,至少要有一个方法 9 if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) && 10 ifc.getMethods().length > 0) { 11 // 用接口代理,也就是jdk 12 hasReasonableProxyInterface = true; 13 break; 14 } 15 } 16 // 将被代理类实现的所有有效接口填充进代理工厂中 17 if (hasReasonableProxyInterface) { 18 for (Class<?> ifc : targetInterfaces) { 19 proxyFactory.addInterface(ifc); 20 } 21 } 22 else { 23 // 若代理类未实现接口,将ProxyTargetClass属性设置为true 24 proxyFactory.setProxyTargetClass(true); 25 } 26 }
被代理类MathCalculator未实现任何接口, 此处执行proxyFactory.setProxyTargetClass(true),下面我们来看看Spring是如何利用上面赋值好的interfaces、proxyTargetClass来选择哪种创建代理对象的方式。
DefaultAopProxyFactory#createAopProxy 判断创建代理对象的核心伪代码:1 // 创建AOP的代理方式 2 public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { 3 // config.isProxyTargetClass() 是否使用Cglib的方式创建代理对象 在上面的准备工作中设置为true 4 if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { 5 // 从AdvisedSupport中获取目标类 类对象 6 Class<?> targetClass = config.getTargetClass(); 7 8 // 判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象;如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象 9 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { 10 return new JdkDynamicAopProxy(config); 11 } 12 // 配置了使用Cglib进行动态代理或者目标类没有接口,那么使用Cglib的方式创建代理对象 13 return new ObjenesisCglibAopProxy(config); 14 } 15 else { 16 // 使用JDK的提供的代理方式生成代理对象 17 return new JdkDynamicAopProxy(config); 18 } 19 }
通过ProxyProcessorSupport#evaluateProxyInterfaces的分析,已经知道AOPConfig中的ProxyTargetClass为true,同时被代理类MathCalculator未实现任何接口,选择Cglib的方式创建代理对象。
2、封装ExposeInvovationInterceptor为Advisor
2.2.2、创建代理对象
1、Enhancer创建代理对象
CglibAopProxy#getProxy 创建动态代理核心伪代码1 // 获取代理对象 2 public Object getProxy(@Nullable ClassLoader classLoader) { 3 // 从advised中获取ioc容器中配置的target对象 4 Class<?> rootClass = this.advised.getTargetClass(); 5 Class<?> proxySuperClass = rootClass; 6 7 // 创建及配置Enhancer 8 Enhancer enhancer = createEnhancer(); 9 10 // 配置超类,代理类实现的接口,回调方法等 11 enhancer.setSuperclass(proxySuperClass); 12 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); 13 enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); 14 enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader)); 15 16 // 获取callbacks 17 Callback[] callbacks = getCallbacks(rootClass); 18 Class<?>[] types = new Class<?>[callbacks.length]; 19 for (int x = 0; x < types.length; x++) { 20 types[x] = callbacks[x].getClass(); 21 } 22 enhancer.setCallbackTypes(types); 23 24 // 通过 Enhancer 生成代理对象,并设置回调 25 return createProxyClassAndInstance(enhancer, callbacks); 26 }
2、获取代理对象的回调方法
创建代理对象核心伪代码中,在getCallbacks(rootClass)步骤获取到Callback[]的信息,CglibAopProxy#getCallbacks 获取回调方法的核心伪代码:1 // 获取回调方法 2 private Callback[] getCallbacks(Class<?> rootClass) throws Exception { 3 // false 4 boolean exposeProxy = this.advised.isExposeProxy(); 5 // false 6 boolean isFrozen = this.advised.isFrozen(); 7 // true 8 boolean isStatic = this.advised.getTargetSource().isStatic(); 9 10 // 创建一个调用AOP流程的拦截器 DynamicAdvisedInterceptor 11 Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised); 12 13 // 获取目标拦截器 14 Callback targetInterceptor; 15 targetInterceptor = (isStatic ? 16 new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : 17 new DynamicUnadvisedInterceptor(this.advised.getTargetSource())); 18 // 获取目标分配器 19 Callback targetDispatcher = (isStatic ? 20 new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp()); 21 22 // 回调方法初始化 23 Callback[] mainCallbacks = new Callback[] { 24 aopInterceptor, // Advice通知 25 targetInterceptor, // 调用目标被代理类的方法 26 new SerializableNoOp(), 27 targetDispatcher, this.advisedDispatcher, 28 new EqualsInterceptor(this.advised), 29 new HashCodeInterceptor(this.advised) 30 }; 31 32 Callback[] callbacks; 33 callbacks = mainCallbacks; 34 35 return callbacks; 36 }
我们来看看callbacks的详情
代理对象创建的流程图
到此,可以回答上述的两个问题了:
1、Callback[] 是什么,在哪里做的初始化 Callback[]是通过Cglib方式创建代理对象的回调方法,在创建被代理类MatchCalculator的代理对象做的初始化。 2、代理对象this.CGLIB$CALLBACK_0 指的是哪个对象 在被代理类bean初始化阶段创建的代理对象 Callback[]在索引为0的位置对应的对象为CglibAopProxy#DynamicAdvisedInterceptor3、AOP通知链控制器 -> ExposeInvocationInterceptor
AbstractAutoProxyCreator#postProcessBeforeInstantiation 在初始化代理对象的后置处理中创建代理对象前,获取通知器Advice执行getAdvicesAndAdvisorsForBean方法,代码流程如下 AbstractAutoProxyCreator#postProcessBeforeInstantiation -> AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean -> AbstractAdvisorAutoProxyCreator#findEligibleAdvisors -> AspectJAwareAdvisorAutoProxyCreator#extendAdvisors -> AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary 核心伪代码如下1 // 在通知链的开始位置添加 2 public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) { 3 // advisors通知器如果为空,则说明不需要代理 4 if (!advisors.isEmpty()) { 5 // 判断是否为Before/After/Around/AfterReturning/AfterThrowing等通知 6 boolean foundAspectJAdvice = false; 7 for (Advisor advisor : advisors) { 8 if (isAspectJAdvice(advisor)) { 9 foundAspectJAdvice = true; 10 break; 11 } 12 } 13 // advisors中不包含ExposeInvocationInterceptor,在通知链的开始位置添加ExposeInvocationInterceptor 14 if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) { 15 advisors.add(0, ExposeInvocationInterceptor.ADVISOR); 16 return true; 17 } 18 } 19 return false; 20 }
4、执行流程
AOP流程执行入口为CglibAopProxy#DynamicAdvisedInterceptor#intercept,核心伪代码
1 // AOP流程执行的入口 2 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { 3 Object oldProxy = null; 4 boolean setProxyContext = false; 5 Object target = null; 6 TargetSource targetSource = this.advised.getTargetSource(); 7 try { 8 if (this.advised.exposeProxy) { 9 // Make invocation available if necessary. 10 oldProxy = AopContext.setCurrentProxy(proxy); 11 setProxyContext = true; 12 } 13 14 target = targetSource.getTarget(); 15 Class<?> targetClass = (target != null ? target.getClass() : null); 16 17 // 从advised中获取ExposeInvocationInterceptor的AOP通知 18 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 19 20 // 通过cglibMethodInvocation来启动advice通知 21 Object retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); 22 retVal = processReturnType(proxy, target, method, retVal); 23 return retVal; 24 } 25 }
CglibMethodInvocation#proceed 核心伪代码:
1 public Object proceed() throws Throwable { 2 // currentInterceptorIndex从 -1开始,集合中通知器是不是都已经被执行 3 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { 4 return invokeJoinpoint(); 5 } 6 7 // 集合中还有Advice未被执行,获取下一个索引位置的Advice 8 Object interceptorOrInterceptionAdvice = 9 this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); 10 11 // 从子类CglibAopProxy#CglibMethodInvocation调用的父类,this为CglibAopProxy#CglibMethodInvocation实例 12 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); 13 14 }
传入的this为CglibAopProxy#CglibMethodInvocation对象:
来看下DynamicAdvisedInterceptor父类ReflectiveMethodInvocation的拦截器通知集合interceptorsAndDynamicMethodMatchers详情:
总结:
从拦截器通知集合interceptorsAndDynamicMethodMatchers索引为0的位置开始取Advisor对象,执行对应的Advisor的invoke方法,下面来看一看Advisor集合中实例的invoke方法。4.1、ExposeInvocationInterceptor 责任链拦截器
ExposeInvocationInterceptor作为Advisor集合中索引位置为0的Advice,第一个执行,invoke方法如下:1 // 线程变量 存储当前AOP调用的方法 2 private static final ThreadLocal<MethodInvocation> invocation = new NamedThreadLocal<>("Current AOP method invocation"); 3 4 // ExposeInvocationInterceptor 的 invoke 5 public Object invoke(MethodInvocation mi) throws Throwable { 6 // 获取当前正在执行的AOP的方法 7 MethodInvocation oldInvocation = invocation.get(); 8 // 将 CglibAopProxy#CglibMethodInvocation 对象放入,为了让AOP链能返回到起始流程,遍历下一个索引的Advisor 9 invocation.set(mi); 10 try { 11 // 执行当前正在执行AOP的Advice的proceed方法,CglibMethodInvocation#proceed()方法 12 return mi.proceed(); 13 } 14 finally { 15 // 线程变量值还原 16 invocation.set(oldInvocation); 17 } 18 }
将CglibMethodInvocation放入线程变量中,返回AOP流程起始位置。
4.2、AspectJAfterThrowingAdvice 异常通知
程序执行未出现异常,执行CglibMethodInvocation#proceed()方法,遍历Advisor获取下一个Advice,执行invoke。1 // AspectJAfterThrowingAdvice的invoke 2 public Object invoke(MethodInvocation mi) throws Throwable { 3 try { 4 // 程序执行未出现异常,执行CglibMethodInvocation#proceed()方法 5 return mi.proceed(); 6 } 7 catch (Throwable ex) { 8 // 出现异常,执行在配置中定义的异常处理逻辑 9 if (shouldInvokeOnThrowing(ex)) { 10 // 从ExposeInvocationInterceptor中获取当前正在执行AOP的Advice,并执行切面方法 11 invokeAdviceMethod(getJoinPointMatch(), null, ex); 12 } 13 throw ex; 14 } 15 }
4.3、AspectJAfterReturningAdvice 后置返回通知
1 // AspectJAfterReturningAdvice 的 invoke 2 public Object invoke(MethodInvocation mi) throws Throwable { 3 // 执行 CglibMethodInvocation#proceed()方法 4 Object retVal = mi.proceed(); 5 // 处理完Around、Before、After通知后,执行AspectJAfterReturningAdvice的afterReturning方法 6 this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); 7 return retVal; 8 }
4.4、AspectJAfterAdvice 后置通知
1 // AspectJAfterAdvice 的 invoke 2 public Object invoke(MethodInvocation mi) throws Throwable { 3 try { 4 // 执行 CglibMethodInvocation#proceed()方法 5 return mi.proceed(); 6 } 7 finally { 8 // 处理完Around、Before通知后,调用配置通知After的相关方法 9 invokeAdviceMethod(getJoinPointMatch(), null, null); 10 } 11 }
4.5、AspectJAroundAdvice 环绕通知
在Around通知中,发现没有mi.proceed()方法,而是直接执行Advice通知的方法1 // AspectJAroundAdvice 的 invoke 2 public Object invoke(MethodInvocation mi) throws Throwable { 3 if (!(mi instanceof ProxyMethodInvocation)) { 4 throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); 5 } 6 // 类型强转为 ProxyMethodInvocation 7 ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; 8 ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi); 9 // 匹配节点 10 JoinPointMatch jpm = getJoinPointMatch(pmi); 11 // 执行Around的通知,执行定义的环绕通知 12 return invokeAdviceMethod(pjp, jpm, null, null); 13 }
通常在自定义的Around方法中,都会看见pjp.proceed(args);的代码片段,这个代码段和 mi.proceed(); 有一样的作用,代表着回到CglibMethodInvocation#proceed方法中,继续获取Advisors中的Advice对象,Advisors中下一个Advice对应的Before通知。
1 // 自定义的环绕通知 2 public Object around(ProceedingJoinPoint pjp) throws Throwable { 3 Signature signature = pjp.getSignature(); 4 Object[] args = pjp.getArgs(); 5 Object result = null; 6 try { 7 System.out.println("log---Around环绕通知start:"+signature.getName()+"方法开始执行,参数为:"+Arrays.asList(args)); 8 //通过反射的方式调用目标的方法,相当于执行method.invoke(),继续获取Advisors中下一个Advice 9 result = pjp.proceed(args); 10 System.out.println("log---Around环绕通知stop"+signature.getName()+"方法执行结束"); 11 } catch (Throwable throwable) { 12 System.out.println("log---Around环绕异常通知:"+signature.getName()+"出现异常"); 13 throw throwable; 14 } 15 return result; 16 }
4.5、AspectJBeforeAdvice 前置通知
1 // AspectJBeforeAdvice 的invoke 2 @Override 3 public Object invoke(MethodInvocation mi) throws Throwable {\ 4 // 执行前置通知,定义的前置通知方法 5 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); 6 // 执行 CglibMethodInvocation#proceed()方法 7 return mi.proceed(); 8 }AspectJBeforeAdvice中,自定义的前置通知执行完成后,再次执行执行 CglibMethodInvocation#proceed()方法,此时Advisors中的所有Advice通知都已经被执行到,CglibMethodInvocation的当前索引下标currentInterceptorIndex与interceptorsAndDynamicMethodMatchers中元素个数相同,此时执行被增强的方法(此例为add方法)。
4.6、AOP执行流程图
标签:Callback,对象,Spring,Object,代理,CALLBACK,源码,CGLIB,AOP From: https://www.cnblogs.com/RunningSnails/p/17013513.html