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

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

相关文章

  • spring 整合 mybatis 中数据源的几种配置方式(总结篇)

    spring 整合 mybatis 中数据源的几种配置方式(总结篇)

    因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-05-05
  • Spring boot使用logback实现日志管理过程详解

    Spring boot使用logback实现日志管理过程详解

    这篇文章主要介绍了Spring boot使用logback实现日志管理过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Java各种锁在工作中使用场景和细节经验总结

    Java各种锁在工作中使用场景和细节经验总结

    本章主要说一说锁在工作中的使用场景,主要以 synchronized 和 CountDownLatch 为例,会分别描述一下这两种锁的使用场景和姿势
    2022-03-03
  • 利用java监听器实现在线人数统计

    利用java监听器实现在线人数统计

    过去使用ASP和ASP.NET两种编程的时候,都写过在线人数统计能,实现功能挺简单的!今天使用java来实现在线人数统计有点另类,是通过Java监听器实现的,需要的朋友可以参考下
    2015-09-09
  • 一篇文章彻底搞懂jdk8线程池

    一篇文章彻底搞懂jdk8线程池

    线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控,这篇文章主要给大家介绍了jdk8线程池的相关资料,需要的朋友可以参考下
    2021-10-10
  • 详解Spring简单容器中的Bean基本加载过程

    详解Spring简单容器中的Bean基本加载过程

    本篇将对定义在 XMl 文件中的 bean,从静态的的定义到变成可以使用的对象的过程,即 bean 的加载和获取的过程进行一个整体的了解
    2017-05-05
  • Java 8 新特性终极版指南详解

    Java 8 新特性终极版指南详解

    Java 8已经公布有一段时间了,种种迹象表明Java 8是一个有重大改变的发行版。本文给大家介绍Java 8 新特性终极版指南详解,需要的朋友参考下
    2016-03-03
  • 如何在IDEA Maven项目中导入本地jar包的步骤

    如何在IDEA Maven项目中导入本地jar包的步骤

    今天小编就为大家分享一篇关于IDEA Maven项目中导入本地jar包的步骤,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 百度翻译API使用详细教程(前端vue+后端springboot)

    百度翻译API使用详细教程(前端vue+后端springboot)

    这篇文章主要给大家介绍了关于百度翻译API使用的相关资料,百度翻译API是百度面向开发者推出的免费翻译服务开放接口,任何第三方应用或网站都可以通过使用百度翻译API为用户提供实时优质的多语言翻译服务,需要的朋友可以参考下
    2024-02-02
  • 利用Java实现简单的猜数字小游戏

    利用Java实现简单的猜数字小游戏

    这篇文章主要为大家详细介绍了如何利用java语言实现猜数字小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04

最新评论