[Spring] The specific implementation process of AOP in AOP analysis in Spring

Get into the habit of writing together! This is the 5th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

Spring's AOP implementation

1. @EnableAspectJAutoProxy enables aspect automatic proxy function

If you want to use AOP, we need to add the @EnableAspectJAutoProxy annotation to the startup class, so start from this annotation

Pay attention to three points

Imported an AspectJAutoProxyRegistrar registration component

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

image-20220407172625393

See what the AspectJAutoProxyRegistrar component has registered and click in

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
复制代码

Implements the ImportBeanDefinitionRegistrar interface, see the rewritten registerBeanDefinitions method

image-20220407173555722

AnnotationAwareAspectJAutoProxyCreator is registered

See what AnnotationAwareAspectJAutoProxyCreator is

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

idea64_SfYMW20idR

It is found that AnnotationAwareAspectJAutoProxyCreator inherits the BeanPostProcessor post processor, that is to say, after SpringIOC initializes each bean, it will execute the implementation class of this BeanPostProcessor, and the rewrite method of postProcessAfterInitialization is in org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

image-20220407174010313

2. Post-processing of bean initialization of AbstractAutoProxyCreator

1. Execute the postProcessAfterInitialization method of the bean post processor

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

Advisors that match the bean currently being created are eventually stored in List eligibleAdvisors

image-20220407193703695

After finding all advisors and filtering, create a proxy class

5. Create a proxy class

Back to the org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary method

image-20220407194010933

The process of getting all the advice has been completed, the next step is to create a proxy class, draw a picture, and organize the process

Guess you like

Origin juejin.im/post/7083839091091243015