【Spring】Spring中AOP解析 中 AOP的具体实现流程

Spring的AOP实现

1.@EnableAspectJAutoProxy 开启切面自动代理功能

如果想使用AOP,我们需要在启动类上添加 @EnableAspectJAutoProxy 注解 所以从这个注解开始动刀

注意三个点

导入了一个 AspectJAutoProxyRegistrar 注册组件

@Import(AspectJAutoProxyRegistrar.class)
boolean proxyTargetClass() default false;   //是否使用CGLB创建代理对象
boolean exposeProxy() default false;  //是否将代理对象放入ThreadLocal ,如果为true,可以通过 AopContext 获取代理对象

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第1张图片

看 AspectJAutoProxyRegistrar 组件注册了什么 点进去

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar

实现了 ImportBeanDefinitionRegistrar 接口 ,看重写的 registerBeanDefinitions 方法

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第2张图片

注册了AnnotationAwareAspectJAutoProxyCreator

看下 AnnotationAwareAspectJAutoProxyCreator 是什么

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

发现 AnnotationAwareAspectJAutoProxyCreator 继承了 BeanPostProcessor 后置处理器 那么,也就是说SpringIOC初始化每一个bean后,都会执行这个BeanPostProcessor 的实现类 ,而postProcessAfterInitialization的重写方法 在 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator中

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第3张图片

2.AbstractAutoProxyCreator的bean初始化后处理

1.执行bean后置处理器的postProcessAfterInitialization方法

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第4张图片

2.过滤无需进行AOP的bean

首先看

Object cacheKey = getCacheKey(bean.getClass(), beanName);

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第5张图片

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第6张图片

跟进

wrapIfNecessary(bean, beanName, cacheKey)

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第7张图片

`Advice Pointcut Advisor AopInfrastructureBean 这四种类型的bean直接返回原对象,不需要进行AOP

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第8张图片

` shouldSkip() 方法留给程序员决定那些bean不需要AOP

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第9张图片

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第10张图片

如下面这个bean 将不会被AOP代理

@Component(value = "com.sgg.proxy.bean.MyBean.ORIGINAL")
public class MyBean {

    @MyAop
    public void method()
    {
        System.out.println("方法执行了");
    }

}

3.先找advice接口的子类

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第11张图片

接下来我们看 getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null) 这个方法

跟进来到 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第12张图片

跟进 findEligibleAdvisors(beanClass, beanName) 方法

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第13张图片

先看 findCandidateAdvisors() 是怎么拿到所有的advice的

跟进来到 org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第14张图片

跟进

BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
      this.beanFactory, Advisor.class, true, false)

注意方法的四个参数

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第15张图片

拿到所有类型为 Advisor 的beanName 注意只是名字 如果有父容器,也取出父容器中的实现了Advisor 接口的bean的Name

image-20220407184314220

拿到所有的beanName后,遍历,

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第16张图片

判断是不是正在创建中,如果正在创建中,跳过 然后调用 this.beanFactory.getBean(name, Advisor.class) 获取(没有就创建bean),放到集合List advisors 中然后返回 至此,拿到了Spring容器中所有的advisor的子类

4.再找标注@Aspect的切面类

回到org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors

通常我们都是使用@Aspect定义一个切面类,这种就需要通过this.aspectJAdvisorsBuilder.buildAspectJAdvisors()去找

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第17张图片

this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

从容器中取出所有类型为Object的bean 也就是取出所有的bean

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第18张图片

拿到class,判断是否有@Aspect注解

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第19张图片

image-20220407192141474

调用 List classAdvisors = this.advisorFactory.getAdvisors(factory) 方法 拿到不同的advisor

首先找到类中所有非定义切入点的方法

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第20张图片

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第21张图片

看adviceMethodFilter过滤器

image-20220407192803150

如果注解类型是PointCut,返回null

回到getAdvisors方法,拿到所有的非@PonitCut的方法后

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第22张图片

调用 getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName) 创建 advisor

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第23张图片

至此,所有的advisor查找完毕 进行下一步过滤操作

4.按Class和方法名筛选advisor

回到 findEligibleAdvisors 方法 看如何筛选的【Spring】Spring中AOP解析 中 AOP的具体实现流程_第24张图片

跟进 【Spring】Spring中AOP解析 中 AOP的具体实现流程_第25张图片

是不是实现了 IntroductionAdvisor 接口,然后调用 canApply(candidate, clazz) 判断是否能应用

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第26张图片

跟进canApply(candidate, clazz) 方法

如果当前advisor 是属于 IntroductionAdvisor ,按Class过滤

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第27张图片

如果当前advisor 是属于 PointcutAdvisor

调用 canApply(pca.getPointcut(), targetClass, hasIntroductions) 方法

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第28张图片

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第29张图片

与当前正在创建的bean匹配的advisor最终都存到了List eligibleAdvisors 中

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第30张图片

查找所有的advisor与过滤筛选完成后,进行代理类的创建

5.创建代理类

回到 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary 方法

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第31张图片

拿到所有的advice的流程已经走完,接下来就是创建代理类了,画张图,整理下流程

【Spring】Spring中AOP解析 中 AOP的具体实现流程_第32张图片

你可能感兴趣的:(spring,spring,spring,boot,spring,cloud)