Springboot源码 AbstractAdvisorAutoProxyCreator解析

 更新时间:2019年08月27日 08:50:59   作者:TheGir1  
这篇文章主要介绍了Springboot源码 AbstractAdvisorAutoProxyCreator解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

摘要:

Spring的代理在上层中主要分为ProxyCreatorSupportProxyProcessorSupport,前者是基于代理工厂,后者是基于后置处理器,也可以认为后置就是自动代理器。当spring容器中需要进行aop进行织入的bean较多时,简单采用ProxyFacotryBean无疑会增加很多工作量(因为每个Bean!都得手动写一个)。所以自动代理就发挥它的作用了。

Spring中自动创建代理器分类

在内部,Spring使用BeanPostProcessor让自动生成代理。基于BeanPostProcessor的自动代理创建器的实现类,将根据一些规则在容器实例化Bean时为匹配的Bean生成代理实例。代理创建器可以分为三类:

  • 基于Bean配置名规则的自动代理生成器:允许为一组特定配置名的Bean自动创建代理实例的代理创建器,实现类为BeanNameAutoProxyCreator
  • 基于Advisor匹配机制的自动代理创建器它会对容器中的所有Advisor进行扫描,自动将这些切面应用到匹配的Bean中,实现类是DefaultAdvisorAutoProxyCreator(它也支持前缀匹配)
  • 基于Bean中AspectJ注解的自动代理生成器:为包含AspectJ注解的切入的Bean自动创建代理实例,实现类是AnnotationAwareAspectJAutoProxyCreator,它是我们的@EnableAspectJAutoProxy导入的,这也是我们当下使用最为广泛的方式~

BeanNameAutoProxyCreator

  package com.github.dqqzj.springboot.aop;  
  import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
  import org.springframework.stereotype.Component;  
  import javax.annotation.PostConstruct;  
  /**
   * @author qinzhongjian
   * @date created in 2019-08-25 09:43
   * @description: TODO
   * @since JDK 1.8.0_212-b10
   */
  @Component
  public class MyBeanNameAutoProxyCreator extends BeanNameAutoProxyCreator {
    @PostConstruct
    public void init() {
      super.setBeanNames("aopService", "abstractAutoProxyCreatorService");
      super.setInterceptorNames("myMethodBeforeAdvice");
    }  
  }

如果你想用自己注册的@Bean代替@EnableAspectJAutoProxy默认给你注册的自动创建器AnnotationAwareAspectJAutoProxyCreator,那么你可以注册一个Bean名称如下的Bean即可:

  // 手动注册一个自动代理创建器,且名字务必叫AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME
  @Bean(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME) 
  public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
    ...
  }

AbstractAutoProxyCreator

  public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
      implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
      ...
  }

AbstractAutoProxyCreator是对自动代理创建器的一个抽象实现。最重要的是,它实现了SmartInstantiationAwareBeanPostProcessor接口,因此会介入到Spring IoC容器Bean实例化的过程,在AbstractAutowireCapableBeanFactory中有这样一段代码

  try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
          return bean;
        }
      }

但是一般都不会生效的,因为这个resolveBeforeInstantiation只是针对有自定义的targetsource,因为自定义的targetsource不是spring的bean那么肯定不需要进行后续的一系列的实例化 初始化。所以可以在resolveBeforeInstantiation直接进行proxy。简单的说吧 ,这个代码可以忽略不计,开发者一般用不到。

如何让resolveBeforeInstantiation直接返回bean?

  package com.github.dqqzj.springboot.aop;
  
  import org.springframework.beans.BeansException;
  import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
  
  /**
   * @author qinzhongjian
   * @date created in 2019-08-25 11:35
   * @description: TODO
   * @since JDK 1.8.0_212-b10
   */
  public class AopServiceInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
      if (beanClass.isInstance(AopService.class)) {
        return new AopService();
      }
      return null;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
    }
  }

这个是spring第一次后置处理器的使用,如果这样直接就返回了,就相当于脱离了IOC的生命周期了一样,依赖注入,属性填充等这些都没有进行处理,所以使用的时候一定要注意,最好别使用这个功能。

在初始化bean的过程中后续还有2个特别重要的后置处理过程,对于循环依赖甚至异步注解事物注解等都有或多或少的影响,后续会继续分析它们。

小结:

SpringAOP应尽量避免自己创建AutoProxyCreator,内部机制及其复杂难免会由于没有想到的问题而出现其他不常见的问题,上面分享的内容很少,原因是我觉得熟悉这个架构设计师最关键的,各种子类的虽然实现大不相同,但是你想全部都记在脑海或者很熟悉那是不太现实的,只有熟悉他的设计才能遇见问题轻易的就能翻源码解决。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 为什么不要使用 async void的原因分析

    为什么不要使用 async void的原因分析

    这篇文章主要介绍了为什么不要使用 async void的原因分析及解决方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • Java中的值传递和引用传递区别解析

    Java中的值传递和引用传递区别解析

    这篇文章主要介绍了Java中的值传递和引用传递区别解析,引用类型的变量保存引用值,“引用值”指向内存空间的地址,代表了某个对象的引用,而不是对象本身,对象本身存放在该引用值所表示的地址的位置,包含:数组、类、接口,需要的朋友可以参考下
    2023-11-11
  • Java中的stream流的概念解析及实际运用总结

    Java中的stream流的概念解析及实际运用总结

    流是指传输时的数据,Java为流准备了很多内置类,尤其是IO输入输出流非常常用,这里我们来看一下Java中的stream流的概念解析及实际运用总结
    2016-06-06
  • Java中的可变参数常见用法实例总结

    Java中的可变参数常见用法实例总结

    这篇文章主要介绍了Java中的可变参数常见用法,结合实例形式总结分析了java可变参数的常见功能、使用方法及相关操作注意事项,需要的朋友可以参考下
    2019-10-10
  • EasyExcel实现导入+各种数据校验功能

    EasyExcel实现导入+各种数据校验功能

    这篇文章主要介绍了EasyExcel实现导入+各种数据校验,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • JSP服务器端和前端出现乱码问题解决方案

    JSP服务器端和前端出现乱码问题解决方案

    这篇文章主要介绍了JSP服务器端和前端出现乱码问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • java与c#的语法区别详细介绍

    java与c#的语法区别详细介绍

    由C#转入Java一段时间了,总结下个人认为的Java同C#语法之间的不同之处,有不同意见之处还望各位海涵,刚学Java时觉得语法同C#大致是相同的(应该说C#同Java大致相同
    2012-11-11
  • Mybatis源码解析之事务管理

    Mybatis源码解析之事务管理

    大家好,本篇文章主要讲的是Mybatis源码解析之事务管理,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • 详解Spring Cloud 跨服务数据聚合框架

    详解Spring Cloud 跨服务数据聚合框架

    这篇文章主要介绍了详解Spring Cloud 跨服务数据聚合框架,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • IntelliJ IDEA 2022.2 正式发布新功能体验

    IntelliJ IDEA 2022.2 正式发布新功能体验

    IntelliJ IDEA 2022.2为远程开发功能带来了多项质量改进,使其更美观、更稳定,新版本还具有多项值得注意的升级和改进,下面跟随小编一起看看IDEA 2022.2新版本吧
    2022-08-08

最新评论