AOP是Spring的两大特性之一,本文再来回顾一下AOP的原理
示例
首先定义一个切点:
1 | public interface Performance { |
然后定义一个切面:
1 |
|
最后定义一个配置类和一个启动类:
1 |
|
最后的输出为
1 | Silencing cell phones |
解析配置类
执行到invokeBeanFactoryPostProcessors
方法,获取实现了BeanDefinitionRegistryPostProcessor
接口的类:ConfigurationClassPostProcessor
。
在ConfigurationClassPostProcessor
的processConfigBeanDefinitions
方法中处理配置类。
首先调动ConfigurationClassParser.parse
方法解析配置类。核心方法是processImports(configClass, sourceClass, getImports(sourceClass), true)
。
首先调用getImports(sourceClass)
方法获取配置类中的Import
注释。这里只有一个:org.springframework.context.annotation.AspectJAutoProxyRegistrar
。然后在getImports
方法中加入到ConfigurationClass
的importBeanDefinitionRegistrars
中:
1 | Class<?> candidateClass = candidate.loadClass(); |
加载beanDefinition
调用this.reader.loadBeanDefinitions(configClass)
根据配置类加载额外的beanDefinition。
在之前的配置类解析中,因为@EnableAspectJAutoProxy
注释的存在,ConfigurationClass
的importBeanDefinitionRegistrars
中有一个key为AspectJAutoProxyRegistrar
,value为StandardAnnotationMetadata
的map。
因此在loadBeanDefinitionsForConfigurationClass
方法中调用loadBeanDefinitionsFromRegistrars
,进入AspectJAutoProxyRegistrar.registerBeanDefinitions
方法,该方法会注册一个名为”org.springframework.aop.config.internalAutoProxyCreator”的beanDefintion,类为org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
。
注册BeanPostProcessor
经过前面加载了beanDefinition,在registerBeanPostProcessors
方法中将AnnotationAwareAspectJAutoProxyCreator
注册为BeanPostProcessor
。
bean实例化与初始化
bean创建工作在DefaultListableBeanFactory.doCreateBean
中完成:
- 调用
AbstractAutowireCapableBeanFactory.createBeanInstance
创建bean实例。 - 调用
AbstractAutowireCapableBeanFactory.populateBean
填充bean实例。 - 调用
AbstractAutowireCapableBeanFactory.initializeBean
初始化bean实例
在调用initializeBean来初始化bean实例的代码中,applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
方法遍历所有的BeanPostProcessor
,调用其postProcessAfterInitialization
方法。
重点关注AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization
,它调用AbstractAutoProxyCreator.wrapIfNecessary
如果需要代理则返回经过包装的代理类:
- 调用
AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean
寻找指定bean的Advisor。 - 如果返回的advisor不为null,说明需要创建代理。调用
createProxy
方法对给定的bean创建一个AOP代理,其调用ProxyFactory.getProxy
方法,该方法只有一行代码:
1 | public Object getProxy(ClassLoader classLoader) { |
先调用createAopProxy
创建AopProxy
,再调用getProxy
获取代理对象。
回到AbstractAutowireCapableBeanFactory.initializeBean
方法,wrappedBean再经过applyBeanPostProcessorsAfterInitialization
处理,调用AbstractAutoProxyCreator.postProcessAfterInitialization
,wrappedBean变成了一个代理类。
AOP代理对象的调用
当调用aop代理类的方法时,调用的实际上是JdkDynamicAopProxy.invoke
:
- 首先调用
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)
获取这个方法的拦截链 - 调用
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain)
创建MethodInvocation,将我们之前的代理、目标对象、拦截的method名称、拦截方法的参数、拦截器链全部整合到了ReflectiveMethodInvocation这个类中 - 然后调用
ReflectiveMethodInvocation.proceed
执行一串拦截链