[Spring] El proceso de implementación específico de AOP en el análisis de AOP en Spring

¡Acostúmbrate a escribir juntos! Este es el quinto día de mi participación en el "Nuevo plan diario de Nuggets · Desafío de actualización de abril", haga clic para ver los detalles del evento .

Implementación de AOP de Spring

1. @EnableAspectJAutoProxy habilita la función de proxy automático de aspecto

Si desea usar AOP, debemos agregar la anotación @EnableAspectJAutoProxy a la clase de inicio, así que comience desde esta anotación

Presta atención a tres puntos.

Se importó un componente de registro de AspectJAutoProxyRegistrar

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

imagen-20220407172625393

Vea lo que ha registrado el componente AspectJAutoProxyRegistrar y haga clic en

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
复制代码

Implementa la interfaz ImportBeanDefinitionRegistrar, consulte el método reescrito registerBeanDefinitions

imagen-20220407173555722

AnnotationAwareAspectJAutoProxyCreator está registrado

Vea qué es AnnotationAwareAspectJAutoProxyCreator

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

idea64_SfYMW20idR

Se encuentra que AnnotationAwareAspectJAutoProxyCreator hereda el posprocesador BeanPostProcessor, es decir, después de que SpringIOC inicialice cada bean, ejecutará la clase de implementación de este BeanPostProcessor, y el método de reescritura de postProcessAfterInitialization está en org.springframework.aop.framework.autoproxy. ResumenAutoProxyCreator

imagen-20220407174010313

2. Posprocesamiento de inicialización de bean de AbstractAutoProxyCreator

1. Ejecute el método postProcessAfterInitialization del posprocesador del bean

imagen-20220407175004088

2.过滤无需进行AOP的bean

首先看

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

imagen-20220407180051597

imagen-20220407180246001

跟进

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

imagen-20220407180541891

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

imagen-20220407180652476

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

imagen-20220407180931716

imagen-20220407180939761

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

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

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

}
复制代码

3.先找advice接口的子类

imagen-20220407183406217

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

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

imagen-20220407183538809

跟进 findEligibleAdvisors(beanClass, beanName) 方法

imagen-20220407183728843

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

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

imagen-20220407183946284

跟进

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

注意方法的四个参数

imagen-20220407184237301

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

imagen-20220407184314220

拿到所有的beanName后,遍历,

imagen-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()去找

imagen-20220407191627391

this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
复制代码

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

imagen-20220407191758870

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

imagen-20220407192059106

imagen-20220407192141474

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

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

imagen-20220407192714738

imagen-20220407192734857

看adviceMethodFilter过滤器

imagen-20220407192803150

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

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

imagen-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

Los asesores que coinciden con el bean que se está creando actualmente se almacenan eventualmente en la Lista de asesores elegibles

image-20220407193703695

Después de encontrar todos los asesores y filtrar, cree una clase de proxy

5. Crea una clase de proxy

Volver al método org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary

image-20220407194010933

El proceso de obtener todos los consejos se ha completado, el siguiente paso es crear una clase de proxy, hacer un dibujo y organizar el proceso.

Supongo que te gusta

Origin juejin.im/post/7083839091091243015
Recomendado
Clasificación