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
当ConfiguraitonClassPostProcessor执行完后,beanFactory中增加了咱们的类和AOP的配置。
之后,在registerBeanPostProcessor中将AOP相关的AnnotationAwareAspectJAutoProxyCreator注册进来。一个Bean的后置处理器。
此时BeanFacotry中的BeanPOSTProcessor为
目前为止 我们已经看到了开启AOP后 spring会帮我们注册AnnotationAwareAspectJAutoProxyCreator并将其作为一个Bean的后置处理器
解析Advicce1.什么时候解析
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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)