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执行一串拦截链