作者:港1009 | 来源:互联网 | 2023-08-01 11:07
过去,我见过人们使用以下2种习惯用法从同一@Configuration
注入依赖项:
@Configuration
public class MyConfiguration {
@Bean
public MyBeanDependencyA myBeanDependencyA(){
return new MyBeanDependencyA();
}
@Bean . //IDIOM 1
public MyBeanDependencyB1 myBeanDependencyB1(){
return new MyBeanDependencyB1(myBeanDependencyA());
}
@Bean //IDIOM 2
public MyBeanDependencyB2 myBeanDependencyB2(MyBeanDependencyA myBeanDependencyA){
return new MyBeanDependencyB1(myBeanDependencyA);
}
}
它们之间有实际区别吗?
- Spring是否在IDIOM 1的每次调用中处理整个实例化方法? (如果方法有任何副作用,可能不是幂等的)?
- 在注入IDIOM 1时,Spring是否会注入全局托管实例? (与某些外部进程更改原始单例bean的状态有关)
Spring容器这么聪明吗?
Spring会在每次对IDIOM 1的调用中处理整个实例化方法吗?
否,这称为inter-bean dependencies,该方法在@Bean
类中用@Configuration
注释进行注释,将在spring IOC容器中创建Bean
@Bean批注用于指示方法实例化,配置和初始化要由Spring IoC容器管理的新对象。对于熟悉Spring的XML配置的人,@ Bean批注将起作用与元素具有相同的作用。您可以将@Bean批注方法与任何Spring @Component一起使用,但是,它们通常与@Configuration Bean一起使用。
在注入IDIOM 1时,Spring是否会注入全局托管实例?
是的,如果需要在多个位置使用spring注入相同的bean Basic concepts: @Bean and @Configuration,则这种bean间的依赖关系只能与@Bean
和@Configuration
结合使用,这也阻止了调用同一个bean方法多次。
建议仅在@Configuration类中使用@Bean方法,以确保始终使用“完全”模式。这样可以防止同一@Bean方法多次被意外调用,并有助于减少在“精简”模式下运行时难以跟踪的细微错误。
,
Spring是否在IDIOM 1的每次调用中处理整个实例化方法? (如果方法有任何副作用,可能不是幂等的)?
默认情况下,@Configuration
类在运行时被代理,因此MyBeanDependencyA
将被创建一次,myBeanDependencyA()
将仅被Spring调用一次,并且下次调用将被代理返回相同的实例(就您共享的示例而言)。在上下文中,此bean只会有一个实例,因为它的范围是Singleton
。
在注入IDIOM 1时,Spring是否注入全局托管实例? (与某些外部进程更改原始单例bean的状态有关)
查询到IOC容器时,它将返回Singleton bean的相同实例。由于它是Singleton
,因此对该bean的所有更改(如果它是可变的)对于引用该bean的组件都是可见的。
另一方面,您不能使用Spring 5.2来禁用配置类的自动代理:
@Configuration(proxyBeanMethods = false)
这将防止代理使用其他@Bean
方法调用的@Bean
注释的方法的调用。