@EnableAspectJAutoProxy注解用于开启AOP功能,那么这个注解底层到底做了什么呢?
查看@EnableAspectJAutoProxy的源码,发现它使用@Import注解向Spring容器中注入了一个类型为AspectJAutoProxyRegistrar的Bean:
AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,而ImportBeanDefinitionRegistrar是spring提供的扩展点之一,主要用来向容器中注入BeanDefinition,spring会根据BeanDefinion来生成Bean。
那么AspectJAutoProxyRegistrar到底向容器中注入了什么BeanDefinion呢?
org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
从源码可以发现AspectJAutoProxyRegistrar向容器中注入了一个类型为AnnotationAwareAspectJAutoProxyCreator的Bean。
那么AnnotationAwareAspectJAutoProxyCreator又是干什么的呢?
AnnotationAwareAspectJAutoProxyCreator主要实现了三个接口(由父类AbstractAutoProxyCreator实现):
实现了BeanFactoryAware,内部持有BeanFactory的引用。实现了SmartInstantiationAwareBeanPostProcessor(InstantiationAwareBeanPostProcessor).postProcessBeforeInstantiation,这个方法在bean的实例化(bean创建之前)之前执行。实现了BeanPostProcessor.postProcessBeforeInitialization(),这个方法在bean的初始化之前(bean创建之后,属性被赋值之前)执行,BeanPostProcessor.postProcessAfterInitialization()在bean的初始化之后执行。AnnotationAwareAspectJAutoProxyCreator的继承结构:
找切面org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply
代理对象的创建代理对象的创建时机位于bean的初始化之后,因为代理对象内部还是需要去调用目标对象的方法,所以需要让目标对象实例化并完成初始化后才会创建代理对象。
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
这里主要看JDK动态代理的实现,Proxy.newProxyInstance()的第三个参数为InvocationHandler,而这里传的是this,也就是当前的类肯定实现了InvocationHandler接口。
代理方法的执行由于是JDK动态代理,那么代理方法的调用肯定会进入InvocationHandler.invoke()方法中,这里的InvocationHandler的实现类为org.springframework.aop.framework.JdkDynamicAopProxy。
org.springframework.aop.framework.JdkDynamicAopProxy#invoke
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
interceptorsAndDynamicMethodMatchers中第一个advice为org.springframework.aop.interceptor.ExposeInvocationInterceptor。
ExposeInvocationInterceptor#invokeorg.springframework.aop.interceptor.ExposeInvocationInterceptor#invoke
ExposeInvocationInterceptor#invoke,只干了一件事就是将MethodInvocation加入到了ThreadLocal中,这样后续可以在其他地方使用ExposeInvocationInterceptor#currentInvocation获取到MethodInvocation,而MethodInvocation中封装了目标对象,目标方法,方法参数等信息。
环绕通知的执行org.springframework.aop.aspectj.AspectJAroundAdvice#invoke
这里会去调用环绕通知的增强方法,而环绕通知的增强方法中会执行proceedingJoinPoint.proceed(),这样就会调用下一个MethodInterceptor–>MethodBeforeAdviceInterceptor。
前置通知的执行org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor
这里又会调用MethodInvocation.proceed()传递给下一个MethodInterceptor。
后置通知的执行org.springframework.aop.aspectj.AspectJAfterAdvice#invoke
先执行MethodInvocation.proceed(),最后在finally块中调用后置通知的增强,不管目标方法有没有抛出异常,finally代码块中的代码都会执行,也就是不管目标方法有没有抛出异常,后置通知都会执行。
返回后通知的执行org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor#invoke
先执行MethodInvocation.proceed(),然后再执行返回后通知的增强。
异常通知的执行org.springframework.aop.aspectj.AspectJAfterThrowingAdvice#invoke
先执行MethodInvocation.proceed(),如果目标方法抛出了异常就会执行异常通知的增强,然后抛出异常,所以这时返回后通知的增强就不会执行了。
总结各种通知的执行顺序:
到此这篇关于spring AOP原理及源码分析的文章就介绍到这了,更多相关spring AOP原理源码内容请搜索七叶笔记以前的文章或继续浏览下面的相关文章希望大家以后多多支持七叶笔记!