¡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 获取代理对象
复制代码
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
AnnotationAwareAspectJAutoProxyCreator está registrado
Vea qué es AnnotationAwareAspectJAutoProxyCreator
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
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
2. Posprocesamiento de inicialización de bean de AbstractAutoProxyCreator
1. Ejecute el método postProcessAfterInitialization del posprocesador del bean
2.过滤无需进行AOP的bean
首先看
Object cacheKey = getCacheKey(bean.getClass(), beanName);
复制代码
跟进
wrapIfNecessary(bean, beanName, cacheKey)
复制代码
`Advice Pointcut Advisor AopInfrastructureBean 这四种类型的bean直接返回原对象,不需要进行AOP
` shouldSkip() 方法留给程序员决定那些bean不需要AOP
如下面这个bean 将不会被AOP代理
@Component(value = "com.sgg.proxy.bean.MyBean.ORIGINAL")
public class MyBean {
@MyAop
public void method()
{
System.out.println("方法执行了");
}
}
复制代码
3.先找advice接口的子类
接下来我们看 getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null) 这个方法
跟进来到 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean
跟进 findEligibleAdvisors(beanClass, beanName) 方法
先看 findCandidateAdvisors() 是怎么拿到所有的advice的
跟进来到 org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()
跟进
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false)
复制代码
注意方法的四个参数
拿到所有类型为 Advisor 的beanName 注意只是名字 如果有父容器,也取出父容器中的实现了Advisor 接口的bean的Name
拿到所有的beanName后,遍历,
判断是不是正在创建中,如果正在创建中,跳过 然后调用 this.beanFactory.getBean(name, Advisor.class) 获取(没有就创建bean),放到集合List advisors 中然后返回 至此,拿到了Spring容器中所有的advisor的子类
4.再找标注@Aspect的切面类
回到org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors
通常我们都是使用@Aspect定义一个切面类,这种就需要通过this.aspectJAdvisorsBuilder.buildAspectJAdvisors()去找
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
复制代码
从容器中取出所有类型为Object的bean 也就是取出所有的bean
拿到class,判断是否有@Aspect注解
调用 List classAdvisors = this.advisorFactory.getAdvisors(factory) 方法 拿到不同的advisor
首先找到类中所有非定义切入点的方法
看adviceMethodFilter过滤器
如果注解类型是PointCut,返回null
回到getAdvisors方法,拿到所有的非@PonitCut的方法后
调用 getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName) 创建 advisor
至此,所有的advisor查找完毕 进行下一步过滤操作
4.按Class和方法名筛选advisor
回到 findEligibleAdvisors 方法 看如何筛选的
跟进
是不是实现了 IntroductionAdvisor 接口,然后调用 canApply(candidate, clazz) 判断是否能应用
跟进canApply(candidate, clazz) 方法
如果当前advisor 是属于 IntroductionAdvisor ,按Class过滤
如果当前advisor 是属于 PointcutAdvisor
调用 canApply(pca.getPointcut(), targetClass, hasIntroductions) 方法
Los asesores que coinciden con el bean que se está creando actualmente se almacenan eventualmente en la Lista de asesores elegibles
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
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.