Spring AOP(二) 三种自动代理器

本章会讲解三个自动代理器
1、BeanNameAutoProxyCreator(需要写被代理的bean名字,和代理的逻辑类名字)
2、DefaultAdvisorAutoProxyCreator(需要继承Advior)
3、@EnableAspectJAutoProxy利用注解开启
我们先从简单的BeanNameAutoProxyCreator 在看 中等难度的DefaultAdvisorAutoProxyCreator 在看 现在使用的@EnableAspectJAutoProxy

1、BeanNameAutoProxyCreator(需要写被代理的bean名字,和代理的逻辑类名字)

在这里插入图片描述
我们先看一下类图

在这里插入图片描述

发现这个类是继承于BeanPostProcessor 的\

我们在看一下@Bean里的方法内容
在这里插入图片描述
我们先看一下这个setBeanNames(),因为这个是BeanNameAutoProxyCreator独特方法

org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator#setBeanNames
在这里插入图片描述

其实就是用了一个List来存放BeanNames

接下来我们就详细的看一下这个BeanNameAutoProxyCreator这个类
但是这个类其实没有什么内容,我们主要是看父类AbstractAutoProxyCreator

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
在这里插入图片描述
这里我们来到正常情况进行AOP的后置处理器这里

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
在这里插入图片描述
这里BeanNameAutoProxyCreator不会使用上面判断的,上面的三个if都会直接过

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean
在这里插入图片描述

org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator#getAdvicesAndAdvisorsForBean
在这里插入图片描述

这里是根据BeanName去匹配的,如果BeanName 存在的话就返回Object[0]

这里我们再回来
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
在这里插入图片描述

在这里会直接代理,只要我们的name匹配

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
在这里插入图片描述

这里BeanNameAutoProxyCreator结束

2、DefaultAdvisorAutoProxyCreator(需要继承Advior)

这个类我们看一下类图
在这里插入图片描述

这里你会发现这个类也是BeanPostProcessor

但是这个类 和BeanNameAutoProxyCreator继承有一点区别

BeanNameAutoProxyCreator ----AbstractAutoProxyCreator

DefaultAdvisorAutoProxyCreator  -----> AbstractAdvisorAutoProxyCreator  -----> AbstractAutoProxyCreator

这个DefaultAdvisorAutoProxyCretorBeanNameAutoProxyCreator 要多继承了一个

接来下我们看代码

还是从这里开始
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
在这里插入图片描述
这里代码我们先会一行一行解释
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary在这里插入图片描述

if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {

StringUtils.hasLength(beanName) 判断BeanName == null 

this.targetSourcedBeans.contains(beanName) 如果在前面提前AOP的话就会在这里集合里添加内容

在这里插入图片描述
在这里插入图片描述
下一行解释
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
在这里插入图片描述
这里的解释看注释和下面的Map解释
在这里插入图片描述
下一行解释
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
在这里插入图片描述

if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) 

isInfrastructureClass(bean.getClass()) : 判断是否是PointcutAdvisorAdviceAopInfrastructureBean类型的
shouldSkip(bean.getClass(), beanName):判断是否要跳过,不过这个一般都是@EnableAspectJAutoProxy注解里用的类使用的,我们在3会看到

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass在这里插入图片描述
下一行解释
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary在这里插入图片描述
这里的处理方式和上面的BeanName处理方式又是不一样的org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean
在这里插入图片描述

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
在这里插入图片描述

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
在这里插入图片描述
这里我们先看第一个方法
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
在这里插入图片描述
注意这里,如果是注解版本的会先调用注解版本的后调用父类的
org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans在这里插入图片描述

这里就是获取当前BeanFactory里所有Advisor类型的beean,然后添加到集合里

我们在回到这里
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors在这里插入图片描述
这个方法作用就是找到匹配咱们BeanClass的Advisor,吧这个筛选出来

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply
在这里插入图片描述

org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply
在这里插入图片描述

org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Advisor, java.lang.Class<?>, boolean)在这里插入图片描述

根据pointcut来匹配

这里DefaultAdvisorAutoProxyCreator也就说到这里了

3、@EnableAspectJAutoProxy利用注解开启

我们先点开这个注解 看看这个注解干了什么
在这里插入图片描述

org.springframework.context.annotation.AspectJAutoProxyRegistrar#registerBeanDefinitions
在这里插入图片描述

这个方法注册了一个BeanDefinition给Spring,我们看一下注册了什么给Spring

org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
在这里插入图片描述

org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
在这里插入图片描述
我们看一下这个类,首先看一下类图
在这里插入图片描述

这里你会发现这个类也是BeanPostProcessor


但是这个类 和BeanNameAutoProxyCreatorDefaultAdvisorAutoProxyCreator  继承有一点区别


BeanNameAutoProxyCreator ----AbstractAutoProxyCreator


DefaultAdvisorAutoProxyCreator  -----> AbstractAdvisorAutoProxyCreator  -----> AbstractAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator -----> AspectJAwareAdvisorAutoProxyCreator -----> AbstractAdvisorAutoProxyCreator  -----> AbstractAutoProxyCreator

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
在这里插入图片描述
还是从这里开始

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
在这里插入图片描述

org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
在这里插入图片描述

这里就是找@Aspect注解的类
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
在这里插入图片描述

org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors

public List<Advisor> buildAspectJAdvisors() {
   List<String> aspectNames = this.aspectBeanNames;


   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            List<Advisor> advisors = new ArrayList<>();
            aspectNames = new ArrayList<>();
            // 拿到beanFactory中所有的bean
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            for (String beanName : beanNames) {
               // 是不是一个合格的Aspect的beanName
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               // We must be careful not to instantiate beans eagerly as in this case they
               // would be cached by the Spring container but would not have been weaved.
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               // beanType是不是一个切面,判断beanType上是否存在@Aspect注解
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  //
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {


                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                     // 解析Advisor (解析@before,@after这些注解)
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     if (this.beanFactory.isSingleton(beanName)) {
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                        this.aspectFactoryCache.put(beanName, factory);
                     }
                     advisors.addAll(classAdvisors);
                  }
                  else {
                     // Per target or per this.
                     if (this.beanFactory.isSingleton(beanName)) {
                        throw new IllegalArgumentException("Bean with name '" + beanName +
                              "' is a singleton, but aspect instantiation model is not singleton");
                     }
                     MetadataAwareAspectInstanceFactory factory =
                           new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                     this.aspectFactoryCache.put(beanName, factory);
                     advisors.addAll(this.advisorFactory.getAdvisors(factory));
                  }
               }
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
         }
      }
   }


   if (aspectNames.isEmpty()) {
      return Collections.emptyList();
   }
   List<Advisor> advisors = new ArrayList<>();
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         advisors.addAll(cachedAdvisors);
      }
      else {
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}

org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors
在这里插入图片描述

这里会遍历所有的方法,遍历所有非@PointCut的方法,获取@Before、@After等注解中的表达式切点,加上当前方法(也就是代理逻辑)一起封装为一个Advisor

org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor
在这里插入图片描述

把满足的条件的生成InstantiationModelAwarePointcutAdvisorImpl这个类也就是Advisor

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值