文章目录
SpringBoot 注解方式使用 @EnableAspectJAutoProxy 开启 AOP 功能, 该注解通过 @Import(ImportBeanDefinitionRegistrar) 的方式导入并注册了一个 BeanDefinition, 即 AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
最终实现了 3 个 BeanPostProcessor, 在 IoC 的第二阶段发光发热
接口 | 方法 | 实现类#实现方法 | 用途 | 调用时机 |
---|---|---|---|---|
InstantiationAwareBeanPostProcessor | postProcessBeforeInstantiation | AbstractAutoProxyCreator | 解析切面 | 实例化之前 |
BeanPostProcessor | postProcessAfterInitailization | AbstractAutoProxyCreato | 创建动态代理 | 初始化之后 |
SmartInstantiationAwareBeanPostProcessor | getEarlyBeanReference | AbstractAutoProxyCreator | 循环依赖下创建动态代理 | 循环依赖时(实例化后初始化前) |
基础 - Spring AOP 实现方式
- Advice: 增强方法的逻辑
- PointCut: 指定实现某种规则的 matches 方法来匹配类和方法, 匹配到的方法会使用 Advice 做增强. 如果一个 Bean 里面有方法被匹配到了, 说明该 Bean 需要做动态代理
- Advisor: 封装了 Advice 和 PointCut. 调用方法时, 使用责任链的方式逐个调用 Advisor
Spring AOP 注解方式 的大致流程
Spring IoC 分两个阶段, 第一阶段解析配置类, 得到所有的 BeanDefinition, 第二阶段遍历并 getBean 生成对象
createBean 分三个步骤, 实例化, 填充属性, 初始化
- 在实例化之前, 解析切面, 获取所有的 Advisor
- 创建代理对象, 分初始化后的正常创建和循环依赖中(getEarlyBeanReference)的提前创建. 生成代理对象时会找到适用的 Advisor 列表并设值到代理对象中
- 调用方法时应用 Advisor
解析切面
首先从 BeanFactory(包含层级) 中找到所有 Advisor 类型的 Bean, 然后再找到被 @Aspect 注解标记的 Bean, 将其中的 @Before, @After 等增强逻辑构建成为 Advisor 对象, 将所有的
正常创建代理
创建一个动态代理类(jdk/cglib)
循环依赖创建代理
调用增强方法
调用被代理类的方法时,找到他的所有增强器,并增强当前的方法
解析切面
createBean - resolveBeforeInstantiation - applyBeanPostProcessorsBeforeInstantiation - 遍历所有 BeanPostProcessor, 判断是 InstantiationAwareBeanPostProcessor 的话, 调用其 postProcessBeforeInstantiation 方法, AnnotationAwareAspectJAutoProxyCreator 的该方法在这时被执行
// AbstractAutoProxyCreator#postProcessBeforeInstantiation
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 判断该 Bean 是否已经被解析过了, 则跳过, advisedBeans 里面存的就是解析过的 Bean
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 如果该 Bean 是 Advice, PointCut, Advisor, AopInfrastructureBean 等类型
// 不用把它们当做是 Bean, 而是作为 Bean 的增强会在 shouldSkip 里面单独处理
// 为什么要 shouldSkip? 其实没太看明白
// shouldSkip, 注意子类覆盖该方法, AspectJAwareAdvisorAutoProxyCreator.shouldSkip
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
// 将该 Bean 标记为无需增强
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// ...
return null;
}
// AspectJAwareAdvisorAutoProxyCreator#shouldSkip
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
// 找到所有的 Advisor, 包含 BeanFactory(包含层级) 中的和 @Aspect 注解中定义的方法(封装成为 Advisor), 然后缓存起来
// 这个查找 Advisor 的过程和当前判断的 BeanName 是没有关系的
// findCandidateAdvisors, 注意子类覆盖方法
// org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
// AspectJPointcutAdvisor, 通过 xml <aop:advisor> 解析出来的 advisor
// 从 Advisor 里拿到 切面类的 BeanName, 如果 beanName 是个切面, 和 advice, advisor, aspect 一样, 无需代理, 需要跳过
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
// AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
// 找到所有的 Advisor, 包含 BeanFactory(包含层级) 中的和 @Aspect 注解中定义的方法(封装成为 Advisor)
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 从 BeanFactory(包含层级) 中找到所有实现了 Advisor 接口的 Bean
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 找到被 @Aspect 注解标记的 Bean, 将其中的 @Before,@After 等增强逻辑构建成为 Advisor 对象, 并添加到找到的 Advisor 列表中
if (this.aspectJAdvisorsBuilder != null) {
// buildAspectJAdvisors 方法是有缓存的
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
// AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
// BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
// 从 BeanFactory(包含层级) 中找到所有实现了 Advisor 接口的 Bean
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
// BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
// 找到被 @Aspect 注解标记的 Bean, 将其中的 @Before,@After 等增强逻辑构建成为 Advisor 对象, 并添加到找到的 Advisor 列表中
public List<Advisor> buildAspectJAdvisors() {
// 存放切面 Bean 的 name
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 从 BeanFactory(包含层级) 中拿到所有的 BeanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 如果 Bean 对应的类上有 @Aspect 注解, 且该类不是被 AspectJ 的 Ajc 编译器编译来的, 那就算是一个切面
// 搭建环境的时候, 把编译器设置成为 Ajc, 所有类都会被 Ajc 编译, 所以常规的切面在这里并不会被判定为切面, 理论上并不会被解析, 但是方法确实被增强了, 不知道哪里还做了其他操作
// 正确的做法是: 设置 Ajc 编译器的时候, 记得勾选 "Delegate to Javac", 这样只有 .aj 的会被 Ajc 编译器编译, 其他的 .java 还是 javac 编译器编译
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// 1.找到所有的切面类
// 2.筛选出来包含 @Around,@Before,@After,@AfterReturning,@AfterThrowing 注解的方法
// 3.封装为List<Advisor>
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 将上面找出来的 Advisor 按照 key 为beanName,value 为 List<Advisor> 的形式存入 advisorsCache
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
// 当再次进入该方法,会直接从 advisorsCache 缓存中获取
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
正常创建代理
createBean - doCreateBean - initializeBean(创建 Bean 的第三步, 初始化) - applyBeanPostProcessorsAfterInitialization - 遍历所有 BeanPostProcessor, 调用其 postProcessAfterInitialization 方法, AnnotationAwareAspectJAutoProxyCreator 的该方法在这时被执行