Spring--aop

Spring--aop,第1张

Spring--aop

ProxyFactoryBean方式--一个Bean需要一个ProxyFactoryBean,类级别的拦截

	
	@Bean
	public ProxyFactoryBean calculateProxy() {
		ProxyFactoryBean userService = new ProxyFactoryBean();
		userService.setInterceptorNames("calLogAdvice", "calLogInterceptor"); 
		userService.setTarget(calculate());
		return userService;
	}

BeanNameAutoProxyCreator---自动生成代理,直接使用本类,不再关心代理类

 @Bean
     public BeanNameAutoProxyCreator autoProxyCreator() {
     BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
     //设置要创建代理的那些Bean的名字
     beanNameAutoProxyCreator.setBeanNames("cal*");
     //设置拦截链名字(这些拦截器是有先后顺序的)
     beanNameAutoProxyCreator.setInterceptorNames("calLogInterceptor");
     return beanNameAutoProxyCreator;
     }


		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(FirstAopConfig.class);
        Calculate tulingCalculate = ctx.getBean("calculate",Calculate.class);//我们在使用的时候,完全不需要关心代理了,直接使用原来的类型就可以了,这是非常方便的。
        tulingCalculate.div(1,1);

开启AOP:

@EnableAspectJAutoProxy开启AOP,通过@import(AspectJAutoProxyRegistrar.class)注册相应的beanDefinition

注入AnnotationAwareAspectJAutoProxyCreator类---这个是AOP使用的

 看类图,AnnotationAwareAspectJAutoProxyCreator是一个bean的后置处理器。而且还继承了AbstractAutoProxyCreator.

 修改internalAutoProxyCreator的两个属性的值

2. 扫描Aspect类并注册AOP相关类

执行完this()方法,beanDefinitionMap里面是前5个类,org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry, Object)里面完成注册的。执行完register方法,里面多了mainConfig类。此时还没到扫描advice逻辑。 

最终在里面 通过ConfiguraitonClassPostProcesser里面解析出所有的@Aspect类

拿到Bean之后,ConfigurationClassBeanDefinitonReader开始读取 

此处,会讲跟AOP相关的Bean注入进来 

org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(Map)在这个方法里面会调用到AspectJAutoProxyRegistrar的注册bean的方法,将AnnotationAwareAspectJAutoProxyCreator注册进来

当ConfiguraitonClassPostProcessor执行完后,beanFactory中增加了咱们的类和AOP的配置。

之后,在registerBeanPostProcessor中将AOP相关的AnnotationAwareAspectJAutoProxyCreator注册进来。一个Bean的后置处理器。

此时BeanFacotry中的BeanPOSTProcessor为

目前为止 我们已经看到了开启AOP后 spring会帮我们注册AnnotationAwareAspectJAutoProxyCreator并将其作为一个Bean的后置处理器

解析Advicce

1.什么时候解析

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])

创建第一个自己的bean的时候调用AOP的org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(Class, String)

之后会调用org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()

自此所有的Advisor都解析出来,并放入缓存中 

解析流程:

doCratBean的时候,调用resolveBeforeInstantiation方法调用Bean的后置处理器--》AbstractAutoProxyCreator.postProcessBeforeInstantiation->AspectJAwareAdvisorAutoProxyCreator.shouldSkip->AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()-->BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() 在该方法里面会获取BeanFactory里所有的Object类,然后逐个判断,如果当前BeanName是一个Aspect类,则解析出里面所有的Advisor,并放入advisors的缓存中,key是beanName,values就是对应的Advisor列表

创建一个代理类

在初始化后在applyBeanPostProcessorsAfterInitialization方法中会调用org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(Object, String)的方法

在wrapIfNecessary方法中,

其中,在解析可以用的Advisor的时候,会加入一个org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR

 

 添加的这个会用于构建Advisor链

以上就根据当前be an 获取了他可用的Advisors,之后调用动态代理的创建过程:

 

最后创建出代理类,并放入一级缓存中

 

使用代理类 

获取到的是代理类 

获取到的是代理类:

 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Object, Method, Object[])会调用到预先添加的ExposeInvocationInterceptor的invoke方法

 

 按照Advisors一依次执行增强方法。

参考文章:

https://juejin.cn/post/6844903555531276296

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5686252.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存