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

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

Spring的AOP实现

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

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

注意三个点

导入了一个 AspectJAutoProxyRegistrar 注册组件

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

image-20220407172625393

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

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
复制代码

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

image-20220407173555722

注册了AnnotationAwareAspectJAutoProxyCreator

看下 AnnotationAwareAspectJAutoProxyCreator 是什么

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

扫描二维码关注公众号,回复: 13775080 查看本文章

idea64_SfYMW20idR

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

image-20220407174010313

2.AbstractAutoProxyCreator的bean初始化后处理

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

image-20220407175004088

2.过滤无需进行AOP的bean

首先看

Object cacheKey = getCacheKey(bean.getClass(), beanName);
复制代码

image-20220407180051597

image-20220407180246001

跟进

wrapIfNecessary(bean, beanName, cacheKey)
复制代码

image-20220407180541891

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

image-20220407180652476

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

image-20220407180931716

image-20220407180939761

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

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

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

}
复制代码

3.先找advice接口的子类

image-20220407183406217

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

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

image-20220407183538809

跟进 findEligibleAdvisors(beanClass, beanName) 方法

image-20220407183728843

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

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

image-20220407183946284

跟进

BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
      this.beanFactory, Advisor.class, true, false)
复制代码

注意方法的四个参数

image-20220407184237301

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

image-20220407184314220

拿到所有的beanName后,遍历,

image-20220407184552822

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

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

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

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

image-20220407191627391

this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
复制代码

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

image-20220407191758870

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

image-20220407192059106

image-20220407192141474

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

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

image-20220407192714738

image-20220407192734857

看adviceMethodFilter过滤器

image-20220407192803150

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

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

image-20220407192914987

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

image-20220407193115624

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

4.按Class和方法名筛选advisor

回到 findEligibleAdvisors 方法 看如何筛选的image-20220407185050346

跟进 image-20220407185142494

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

image-20220407185527734

跟进canApply(candidate, clazz) 方法

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

image-20220407185808726

如果当前advisor 是属于 PointcutAdvisor

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

image-20220407190237756

image-20220407190252760

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

image-20220407193703695

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

5.创建代理类

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

image-20220407194010933

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

猜你喜欢

转载自juejin.im/post/7083839091091243015