Spring 5 原始碼解析- AOP原理分析
這裡以 <aop:aspectj-autoproxy /> 開啟 AOP 方式進行程式碼分析。
配置檔案(UserAOPTest-context.xml)資訊:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocationView Code="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="user" class="org.springframework.context.support.learning.aop.UserImpl"/> <bean id="userAspect" class="org.springframework.context.support.learning.aop.UserAspect"/> <!-- 開啟 執行期AOP 織入 --> <aop:aspectj-autoproxy proxy-target-class="false"/> </beans>
測試用例程式碼:
public class UserAOPTest { @Test void aopTestWithJDK(){ GenericXmlApplicationContext ctxView Code= new GenericXmlApplicationContext(getClass(), "UserAOPTest-context.xml"); User user = ctx.getBean(User.class); user.doTask(); } }
程式碼:User
public interface User { String doTask(); }View Code
程式碼:UserImpl
public class UserImpl implements User{ @Override public String doTask() { System.out.println(getClass().toString() + " doTask..."); return "return doTask"; } }View Code
程式碼:UserAspect
@Aspect public class UserAspect { /** Logger used by this class. Available to subclasses. */ protected final Log logger = LogFactory.getLog(getClass()); @Pointcut("execution(public * org.springframework.context.support.learning.aop.User.doTask(..))") public void pointCut(){} @Before("pointCut()") public void before(JoinPoint point) throws Throwable { Signature signature = point.getSignature(); if (logger.isInfoEnabled()) { logger.info("before --> begin Time:" + System.currentTimeMillis()); } } @After("pointCut()") public void after(JoinPoint point) throws Throwable { Signature signature = point.getSignature(); if (logger.isInfoEnabled()) { logger.info("after --> begin Time:" + System.currentTimeMillis()); } } @AfterReturning(pointcut="pointCut()", returning="returnValue") public void afterReturning(JoinPoint point, Object returnValue) throws Throwable { Signature signature = point.getSignature(); if (logger.isInfoEnabled()) { logger.info("afterReturning --> begin Time:" + System.currentTimeMillis()); } } @Around("pointCut()") public void around(ProceedingJoinPoint pjp) throws Throwable { Signature signature = pjp.getSignature(); if (logger.isInfoEnabled()) { logger.info("around --> begin Time:" + System.currentTimeMillis()); } pjp.proceed(); if (logger.isInfoEnabled()) { logger.info("around --> end Time:" + System.currentTimeMillis()); } } @AfterThrowing(throwing="ex", pointcut="pointCut()") public void afterThrowing(Throwable ex) { if (logger.isInfoEnabled()) { logger.info("目標方法中丟擲的異常:" + ex); logger.info("afterThrowing --> end Time:" + System.currentTimeMillis()); } } }View Code
一.讀取AOP配置,並根據AOP配置進心初始化
XmlBeanDefinitionReader#registerBeanDefinitions()
XmlBeanDefinitionReader#createReaderContext()
XmlBeanDefinitionReader#getNamespaceHandlerResolver()
XmlBeanDefinitionReader#createDefaultNamespaceHandlerResolver()
1.讀取XML配置檔案時,建立預設 DefaultNamespaceHandlerResolver 例項,準備解析XML配置檔案資訊。
2. 依次迴圈解析 <beans> 節點配置資訊。當遇到 <aop:aspectj-autoproxy /> 節點時,使用META-INF/spring.handlers中配置的處理器進行處理。
(在 DefaultNamespaceHandlerResolver#getHandlerMappings() 中讀取META-INF/spring.handlers配置檔案。)
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
3. 具體解析器進行處理。
BeanDefinitionParserDelegate#parseCustomElement(Element, BeanDefinition)
/** * Parse a custom element (outside of the default namespace). * @param ele the element to parse * @param containingBd the containing bean definition (if any) * @return the resulting bean definition */ @Nullable public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) { String namespaceUri = getNamespaceURI(ele); if (namespaceUri == null) { return null; } NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }View Code
4. 解析器初始化。
AopNamespaceHandler#init()
public class AopNamespaceHandler extends NamespaceHandlerSupport { /** * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}' * and '{@code scoped-proxy}' tags. */ @Override public void init() { // In 2.0 XSD as well as in 2.5+ XSDs registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace in 2.5+ registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); } }View Code
5. 具體配置依次分析:
ConfigBeanDefinitionParser <aop:config> 解析如下配置。現在一般使用註解,很少這麼配置了。
<aop:config> <aop:pointcut id="pointCut" expression="execution(public * org.springframework.context.support.learning.aop.User.doTask(..))"/> <aop:aspect ref="userAspect"> <!--前置增強--> <aop:before method="before" pointcut-ref="pointCut"></aop:before> <!--後置返回增強--> <aop:after-returning method="afterReturning" pointcut-ref="pointCut" returning="returnValue"></aop:after-returning> <!--異常通知--> <aop:after-throwing method="afterThrowing" pointcut-ref="pointCut" throwing="ex"></aop:after-throwing> <!--最終通知--> <aop:after method="after" pointcut-ref="pointCut"></aop:after> <!--環繞通知--> <aop:around method="around" pointcut-ref="pointCut"></aop:around> </aop:aspect> </aop:config>View Code
AspectJAutoProxyBeanDefinitionParser <aop:aspectj-autoproxy/> 解析<aop:aspectj-autoproxy/>配置節點,註冊 AnnotationAwareAspectJAutoProxyCreator 的 BeanDefinition例項。該類實現了 BeanPostProcessor 介面,在建立物件( doCreateBean() )例項時,進行後置處理。
AspectJAutoProxyBeanDefinitionParser#parse
AopNamespaceUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary()
AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry, Object)
registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source)
ScopedProxyBeanDefinitionDecorator <aop:scoped-proxy/> 現在很少使用。
SpringConfiguredBeanDefinitionParser <aop:spring-configured/> 現在很少使用。
二. AOP建立AnnotationAwareAspectJAutoProxyCreator 例項
PostProcessorRegistrationDelegate#registerBeanPostProcessors(ConfigurableListableBeanFactory, AbstractApplicationContext)
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
迴圈註冊 BeanPostProcessors 時,建立 AnnotationAwareAspectJAutoProxyCreator 例項,並新增到 BeanPostProcessor 列表。
AnnotationAwareAspectJAutoProxyCreator 例項初始化時,初始化,建立後期使用的輔助物件例項。
AnnotationAwareAspectJAutoProxyCreator#initBeanFactory()
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory); if (this.aspectJAdvisorFactory == null) { this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory); } this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);View Code
三. 建立業務類例項,並根據切點配置建立代理物件
(一) 建立切面通知(Advice)例項 Advisor。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation()
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation()
org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip()
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()
org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()
在建立物件例項之前,解析當前程式 @Aspect 標記的類資訊 {Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class}。
1. 獲得當前 beanFactory 中配置的所有 beanNames 資訊。
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false)
2. 迴圈遍歷處理 bean 配置。
a. 獲得 beanName 對應的型別。
b. 判斷 beanType 是否是 isAspect(beanType)。
c. 獲取 beanName 對應的所有通知 ( Advice ) 包裝列表 List<Advisor>。
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors()
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisorMethods()
1. 獲取 aspectClass 所有方法(Method),並按 Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class 進行排序。
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor(Method, MetadataAwareAspectInstanceFactory , int , String)
@Override @Nullable public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); }View Code
1.建立方法切點資訊例項。AspectJExpressionPointcut
2. 建立通知和切點關聯物件例項。 InstantiationModelAwarePointcutAdvisorImpl
3. 最終儲存在 org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#advisorsCache 例項中。
InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice()
ReflectiveAspectJAdvisorFactory#getAdvice()
(二). 建立bean 代理物件
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition ,Object[] )
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance(String, RootBeanDefinition, Object[])
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean(String, RootBeanDefinition, BeanWrapper)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization(Object, String)
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(@Nullable, String)
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary(Object bean, String beanName, Object cacheKey)
1. 檢查是否是 AOP 相關的配置或工具類。
2. 檢查是否 滿足AOP代理條件。
3. 獲取滿足條件的通知(advice)。 目標類中,只要有一個方法滿足 切入點(Pointcut)條件,就將通知(advice)新增到代理類攔截器中。
4. 建立AOP代理例項。
/** * Wrap the given bean if necessary, i.e. if it is eligible for being proxied. * @param bean the raw bean instance * @param beanName the name of the bean * @param cacheKey the cache key for metadata access * @return a proxy wrapping the bean, or the raw bean instance as-is */ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }View Code
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource)
org.springframework.aop.framework.ProxyProcessorSupport#evaluateProxyInterfaces(Class<?>, ProxyFactory)
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildAdvisors(String beanName, Object[] specificInterceptors)
org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)
1. 遍歷目標類所有介面。
2. 處理滿足條件的通知和公共通知。
3. 通過代理工廠類,建立代理類。
/** * Create an AOP proxy for the given bean. * @param beanClass the class of the bean * @param beanName the name of the bean * @param specificInterceptors the set of interceptors that is * specific to this bean (may be empty, but not null) * @param targetSource the TargetSource for the proxy, * already pre-configured to access the bean * @return the AOP proxy for the bean * @see #buildAdvisors */ protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // Use original ClassLoader if bean class not locally loaded in overriding class loader ClassLoader classLoader = getProxyClassLoader(); if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) { classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader(); } return proxyFactory.getProxy(classLoader); }View Code
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource)
org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)
org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy()
org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy()
org.springframework.aop.framework.AopProxy#getProxy(java.lang.ClassLoader)
1. 建立 AopProxy 代理例項。這裡區分 JDK動態代理(JdkDynamicAopProxy) 和 Cglib 代理(ObjenesisCglibAopProxy)。
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (!NativeDetector.inNativeImage() && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); }View Code
2. 使用 AopProxy 代理建立最終的代理類。區別兩種代理情況。
AopProxy 建立代理類例項:
JDK 生成動態代理簡單,直接呼叫JDK的方法生成。org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
@Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this); }View Code
JdkDynamic 生成的代理類:
package com.sun.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import org.springframework.context.support.learning.aop.User; public final class $Proxy35 extends Proxy implements User { private static Method m1; private static Method m2; private static Method m3; private static Method m0; public $Proxy35(InvocationHandler var1) throws { super(var1); } public final boolean equals(Object var1) throws { try { return (Boolean)super.h.invoke(this, m1, new Object[]{var1}); } catch (RuntimeException | Error var3) { throw var3; } catch (Throwable var4) { throw new UndeclaredThrowableException(var4); } } public final String toString() throws { try { return (String)super.h.invoke(this, m2, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final String doTask() throws { try { return (String)super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } public final int hashCode() throws { try { return (Integer)super.h.invoke(this, m0, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object")); m2 = Class.forName("java.lang.Object").getMethod("toString"); m3 = Class.forName("org.springframework.context.support.learning.aop.User").getMethod("doTask"); m0 = Class.forName("java.lang.Object").getMethod("hashCode"); } catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage()); } catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage()); } } }View Code
Cglib生成代理類,使用ASM位元組碼,稍微複雜些。 org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
@Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); } try { Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); Class<?> proxySuperClass = rootClass; if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) { proxySuperClass = rootClass.getSuperclass(); Class<?>[] additionalInterfaces = rootClass.getInterfaces(); for (Class<?> additionalInterface : additionalInterfaces) { this.advised.addInterface(additionalInterface); } } // Validate the class, writing log messages as necessary. validateClassIfNecessary(proxySuperClass, classLoader); // Configure CGLIB Enhancer... Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } }View Code
Cglib 生成的代理類太複雜,這裡就不展示。
四. 通過代理類例項呼叫業務方法和增強通知(Advice)
JdkDynamic代理:
org.springframework.aop.framework.JdkDynamicAopProxy#invoke(Object proxy, Method method, Object[] args)
1. 獲得當前方法的 所有通知(Advice) /攔截器。獲取後,快取中放一份。
2. 如果沒找到滿足條件的通知(Advice),則直接呼叫實際方法。AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse)
3. 通過目標方法,方法引數,通知(Advice) 建立呼叫方法的 ReflectiveMethodInvocation 例項。
4. 呼叫 ReflectiveMethodInvocation#proceed()。 這個方法會輪詢呼叫 通知(Advice) ,並最終呼叫實際的方法。
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
@Override @Nullable public Object proceed() throws Throwable { // We start with an index of -1 and increment early. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }View Code
(代理類例項)user.doTask() -> JdkDynamicAopProxy#invoke()
-> ReflectiveMethodInvocation#proceed() -> ExposeInvocationInterceptor#invoke(MethodInvocation mi)
AspectJAroundAdvice#invoke(MethodInvocation mi)
MethodBeforeAdviceInterceptor#invoke(MethodInvocation mi)
AspectJAfterAdvice#invoke(MethodInvocation mi)
AfterReturningAdviceInterceptor#invoke(MethodInvocation mi)
AspectJAfterThrowingAdvice#invoke(MethodInvocation mi)
AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments)
Cglib代理:
org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept
1. 獲得當前方法的 所有通知(Advice) /攔截器。快取中放一份。
2. 如果沒找到滿足條件的通知(Advice),則直接呼叫代理方法。org.springframework.cglib.proxy.MethodProxy#invoke(Object obj, Object[] args)
3. 通過目標方法,方法引數,通知(Advice) 建立呼叫方法的 CglibMethodInvocation 例項。 CglibMethodInvocation 是 ReflectiveMethodInvocation 子類。
4. 呼叫 CglibMethodInvocation#proceed()。 這個方法會輪詢呼叫 通知(Advice) ,並最終呼叫實際的方法。這個和JdkDynamic 類似 。