spring中注入bean有几种方式,spring构造方法注入bean

  spring中注入bean有几种方式,spring构造方法注入bean

  00-1010简介构造方法依赖(推荐)@DependsOn(不推荐)BeanPostProcessor(不推荐)

  

目录

说明

 

  本文介绍了Spring如何控制Bean注入的顺序。

  首先需要注意的是,在bean中添加@Order(xxx)并不能控制bean注入的顺序!

  控制bean的加载顺序的方法

  1.构造方法依赖性

  2.@DependsOn评论

  3.BeanPostProcessor扩展

  bean的初始化顺序和类加载的顺序基本相同:静态变量/语句块=实例变量或初始化语句块=构造方法=@Autowirebean注入顺序。

  00-1010创建两个Bean,并要求在CDemo1之前初始化CDemo2。

  @ component public class c demo 1 { private String name= c demo 1 ;public CDE mo 1(CDE mo 2 CDE mo 2){ system . out . println(name);} } @ component public class c demo 2 { private String name= c demo 2 ;public c c demo 2(){ system . out . println(name);}}结果(如预期)

  限制

  如果存在注入关系,比如:通过构造方法将CDemo2注入到CDemo1中,那么在两个没有注入关系的bean之间指定优先级是不合适的(比如我想让一个bean在所有其他bean初始化之前执行)。

  循环依赖,比如上面CDemo2的构造方法,如果有一个参数是CDemo1,那么就会产生循环依赖,无法启动应用。

  还有一点需要注意的是,构造方法中不能有复杂耗时的逻辑,会拖慢应用的启动时间。

  00-1010为什么不推荐:该方法通过bean的名称(字符串)控制顺序。如果您更改bean的类名,您可能会忘记更改所有使用它的注释,这是一个大问题。

  当一个bean在另一个bean实例化后需要实例化时,可以使用该注释。

  @ depends on( right demo 2 )@ component public class right demo 1 { private String name= right demo 1 ;public right demo 1(){ system . out . println(name);} } @ component public class right demo 2 { private String name= right demo 2 ;public right demo 2(){ system . out . println(name);}}上面的注释是在RightDemo1上解放的,说明RightDemo1的初始化依赖于bean rightDemo2。

  可以控制bean的实例化顺序,但是不能保证bean的初始化顺序(比如构造bean实例后调用@PostConstruct注释的初始化方法)。例如,下面的例子可以说明这个问题。

  @ depends on( right demo 2 )@ component public class right demo 1 { private String name= right demo 1 ;@ Autowired private right demo 2 right demo 2;public right demo 1(){ system . out . println(name);} @ post construct public void init(){ system . out . println(name _ init );} } @ component public class right demo 2 { private String name= right demo 2 ;@ Autowired private right demo 1 right demo 1;公共权利Demo2()

  { System.out.println(name); } @PostConstruct public void init() { System.out.println(name + " _init"); }}结果(先实例的Bean反而在后边执行init)

  

 

  把上面测试代码中的@Autowired的依赖注入删除,即两个bean没有相互注入依赖,再执行,会发现输出顺序又不一样

  

 

  

BeanPostProcessor(不推荐)

一种非典型的使用方式,如非必要,请不要用这种方式来控制bean的加载顺序。

 

  场景1:希望HDemo2在HDemo1之前被加载

  

@Componentpublic class HDemo1 { private String name = "h demo 1"; public HDemo1() { System.out.println(name); }} @Componentpublic class HDemo2 { private String name = "h demo 2"; public HDemo2() { System.out.println(name); }}
@Componentpublic class DemoBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements BeanFactoryAware { private ConfigurableListableBeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) { if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { throw new IllegalArgumentException( "AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory: " + beanFactory); } this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; } @Override @Nullable public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { // 在bean实例化之前做某些操作 if ("HDemo1".equals(beanName)) { HDemo2 demo2 = beanFactory.getBean(HDemo2.class); } return null; }}

将目标集中在postProcessBeforeInstantiation,这个方法在某个bean的实例化之前,会被调用,这就给了我们控制bean加载顺序的机会。

 

  执行结果

  

 

  场景2:希望某个bean在应用启动之后,首先实例化此Bean。

  解决方法:重写DemoBeanPostProcessor的postProcessAfterInstantiation方法。

  

@Componentpublic class DemoBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements BeanFactoryAware { private ConfigurableListableBeanFactory beanFactory; @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if ("application".equals(beanName)) { beanFactory.getBean(FDemo.class); } return true; }} @DependsOn("HDemo")@Componentpublic class FDemo { private String name = "F demo"; public FDemo() { System.out.println(name); }} @Componentpublic class HDemo { private String name = "H demo"; public HDemo() { System.out.println(name); }}

执行结果(HDemo, FDemo的实例化顺序放在了最前面)

 

  

 

  到此这篇关于一文详解Spring如何控制Bean注入的顺序的文章就介绍到这了,更多相关Spring控制Bean注入顺序内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • spring编程式事务处理,spring编程事务
  • spring编程式事务处理,spring编程事务,详解Spring学习之编程式事务管理
  • spring的核心功能模块有几个,列举一些重要的spring模块
  • spring的核心功能模块有几个,列举一些重要的spring模块,七个Spring核心模块详解
  • spring注解和springmvc的注解,SpringMVC常用注解
  • spring注解和springmvc的注解,SpringMVC常用注解,详解springmvc常用5种注解
  • spring实现ioc的四种方法,spring的ioc的三种实现方式
  • spring实现ioc的四种方法,spring的ioc的三种实现方式,简单实现Spring的IOC原理详解
  • spring事务失效问题分析及解决方案怎么做,spring 事务失效情况
  • spring事务失效问题分析及解决方案怎么做,spring 事务失效情况,Spring事务失效问题分析及解决方案
  • spring5.0新特性,spring4新特性
  • spring5.0新特性,spring4新特性,spring5新特性全面介绍
  • spring ioc以及aop原理,springmvc aop原理
  • spring ioc以及aop原理,springmvc aop原理,深入浅析Spring 的aop实现原理
  • Spring cloud网关,spring cloud zuul作用
  • 留言与评论(共有 条评论)
       
    验证码: