文章目录
1. @EnableAspectJAutoProxy
注解
总所周知,使用spring-aop
,需要在类上标注@EnableAspectJAutoProxy
注解
而@EnableAspectJAutoProxy
注解使用@Import
注解导入了AspectJAutoProxyRegistrar
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy { /** ... **/ }
2. AspectJAutoProxyRegistrar
而AspectJAutoProxyRegistrar
向Spring容器中注入了AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
是一个BeanPostProcessor
也是Spring-AOP
中最最核心的类,由该类介入bean
的创建流程, 为合适的bean
创建代理对象
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 向容器中注入AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
/** 忽略
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
**/
}
3. AnnotationAwareAspectJAutoProxyCreator
继承关系图
4. AbstractAutoProxyCreator
4.1 postProcessAfterInitialization()
postProcessAfterInitialization()
不用多介绍,BeanPostProcessor
中定义的后置处理方法
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
if (this.earlyProxyReferences.remove(cacheKey) != bean)
什么条件下这个判断才能成功呢?
- earlyProxyReferences.remove(cacheKey) == null , 也就是说没有被提前创建
- 如果被提前创建了
earlyProxyReferences.remove(cacheKey)
返回的对象一定是== bean
的
这样写的好处就是一行代码做了两件事,
- 如果没有提前创建, 那么执行
wrapIfNecessary
方法 - 否则从容器中移除
有 Doug Lea 写代码那味了, 如果没有花括号就更像了(手动狗头)
4.2 wrapIfNecessary()
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 进入`if`分支后, 证明这个`bean`不需要被代理, 直接返回`bean`
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != null) {
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;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName))
isInfrastructureClass(bean.getClass()
该类是下面任一的话返回true
Advice
Pointcut
Advisor
AopInfrastructureBean
因为这些类都是用于辅助创建代理对象的,不应该也不需要被代理
shouldSkip(bean.getClass(), beanName)
其实这里子类重新了该方法AspectJAwareAdvisorAutoProxyCreator#shouldSkip
还是在判断当前类是否是Aspect
,用于兼容xml使用beanName的方式配置aspect
,没有必要深究
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null)
核心方法,找到可以为当前类使用的
advisor
子类重写了该方法,具体会调用到AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
—> 进入5跟踪源码
5. AbstractAdvisorAutoProxyCreator
5.1 getAdvicesAndAdvisorsForBean()
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 找到所有可用的 { Advisor }
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
// 没有找到, 返回NULL
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
// 作为数组返回
return advisors.toArray();
}
5.2 findEligibleAdvisors()
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 1.1 从Spring容器中获取所有的 { Advisor }
// 1.2 从Spring容器中获取所有的 { Bean } , 如果 { Bean } 使用了 { @Aspect }注解
// 那么将其包装成 { Advisor }
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 2. 找到可以为 { beanClass } 使用的 { Advisor }
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 忽略
extendAdvisors(eligibleAdvisors);
// 3. 按照 { @Order } 和 { @PriorityOrder } 注解对Advisors排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
List<Advisor> candidateAdvisors = findCandidateAdvisors();
在AnnotationAwareAspectJAutoProxyCreator
重写了这个方法
PS:
AnnotationAwareAspectJAutoProxyCreator
也就是使用@EnableAspectJAutoProxy
注解导入进Spring容器的类
—> 进入5.3跟踪源码
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
并不是所有的
Advisor
都是可以为当前bean
服务的,在ProxyFactory使用篇有提到过, Advisor需要根据Class
和Method
匹配上才被使用
调用findAdvisorsThatCanApply
,找到可以被当前Bean
使用的Advisor
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
排序,用于支持
Advisor
上的@Order
和@PriorityOrdered
- 返回Advisors
5.3 AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
super.findCandidateAdvisors();
从Spring容器中获取所有类型为
Advisor
的bean
Spring很多功能都是通过向容器中注册Advisor
来实现的, 例如
BeanFactoryCacheOperationSourceAdvisor
支持Spring-Cache的,例如@Cacheable
,@CacheEvict
,@Cacheput
AsyncAnnotationAdvisor
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
很重要
我们使用@Aspect
注解定义的切面,就是在这里被找到并且被包装为Advisor
的
—> 进入5.4跟踪源码
5.4 BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
// 简化了一部分代码, 删除了一些比较函件的分支
public List<Advisor> buildAspectJAdvisors() {
// 1. 结果集合, 用于返回
List<Advisor> advisors = new ArrayList<>();
// 2. 从Spring容器中获取所有的Bean
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
// 3. 判断类上是否有 { @Aspect }注解, 如果有, 返回true
if (this.advisorFactory.isAspect(beanType)) {
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 包装成MetadataAwareAspectInstanceFactory, 无需深究
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 4. 转换为 { Advisor }
// 为什么可以转换为多个?
// 例如类里的有方法包标注了`AspectJ的注解` { @Around / @Before / @After... }
// 那么就会被转换为多个 { Advisor }
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
advisors.addAll(classAdvisors);
}
}
// 5. 返回结果
return advisors;
}
根据代码分析得到:
- 找到Spring容器中所有的bean
- 找到被
@Aspect
标注的类- 根据该类中的方法, 包装成0个或多个
Advisor
6. AbstractAutoProxyCreator
6.1 继续分析wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 进入`if`分支后, 证明这个`bean`不需要被代理, 直接返回`bean`
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 前面分析了 { specificInterceptors } 是如何得到的
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 从这里开始继续分析
if (specificInterceptors != null) {
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;
}
如果specificInterceptors
为空,那么表示没有为当前bean找到合适的advisor
,也就不需要为其创建代理,直接把bean
返回
否则
调用AbstractAutoProxyCreator
类的createProxy
方法
6.2 createProxy
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 忽略
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
// 用于辅助这个方法的: 判断Aop对象真正的class
/** {@link AutoProxyUtils#determineTargetClass(ConfigurableListableBeanFactory, String)} */
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 1. 创建ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
// 2. 忽略
proxyFactory.copyFrom(this);
// 3. 忽略: 判断是优先基于类代理还是接口代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 4. 将 { specificInterceptors } 转换为 { Advisor[] }
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 5. 赋值给proxyFactory
proxyFactory.addAdvisors(advisors);
// 6. 赋值targetSource, 这里的targetSource是 { class:SingletonTargetSource }
proxyFactory.setTargetSource(targetSource);
// 7. 扩展点, 默认无
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
// 8. 告诉ProxyFactory已经过滤过了, 在创建代理时无需再过滤一次
// "已经过滤过了"是什么意思? 就是指当前的`advisor`都是适用于当前`bean`的
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 9. 创建代理
return proxyFactory.getProxy(getProxyClassLoader());
}
- 创建
proxyFactory
- 为
proxyFactory
赋值 - 使用
proxyFactory
创建代理对象并且返回
至此Spring-AOP
介入对象创建生命周期并且创建代理的流程就已经结束了
具体ProxyFactory
是如何创建代理的,可以查看这篇文章