我有一个Spring Configuration类,如下所示:
@Configuration
public class MyDependencyConfig {
@Bean
@Primary
public MyDependency getMyDependency(){
System.out.println("getMyDependency");
return Mockito.mock(MyDependency.class);
}
@Bean
public MyDependency getMyDependency2(){
System.out.println("getMyDependency2");
return Mockito.mock(MyDependency.class);
}
}
我的代码中有其他地方:
@Autowired
MyDependency foo
为什么在应用程序上下文启动时,我的控制台打印
getMyDependency
getMyDependency2
何时只使用来自getMyDependency()的bean?我正在使用spring boot-1.5.1.RELEASE
谢天谢地, 杰森
答案 0 :(得分:6)
Spring配置在Spring上下文启动时实例化并加载Spring容器中所有已声明和必需的bean。
因此,即使您不使用配置中定义的所有bean,也会调用配置中注释为@Bean
的方法。
The @Primary
annotation还有另一个目标。
它表示在多个bean时应该优先考虑bean 候选人有资格自动使用单值依赖。如果 在候选人中确实存在一个“主要”bean,它将是 自动装配价值。
当你有多个候选bean时,这只是一种不系统地指定@Qualifier
注释的方法。
例如,在您的情况下,将两个bean中的一个指定为primary
:
@Bean
@Primary
public MyDependency getMyDependency(){
System.out.println("getMyDependency");
return Mockito.mock(MyDependency.class);
}
您无需指定限定符"getMyDependency"
来注入指定为primary
的限定符:
@Autowired
@Qualifier("getMyDependency")
MyDependency foo;
你可以直接这样做:
@Autowired
MyDependency foo;
对于第二个未指定为@Primary
的bean:
@Bean
public MyDependency getMyDependency2(){
System.out.println("getMyDependency2");
return Mockito.mock(MyDependency.class);
}
当您想要注射时,您必须指定@Qualifier
以清除歧义:
@Autowired
@Qualifier("getMyDependency2")
MyDependency foo;
不建议以懒惰的方式加载bean,因为它会延迟配置错误的捕获。所以,默认情况下是急切的。
您在评论中提供的link中有更多详细信息。
现在,如果要阻止此默认行为并为bean定义延迟初始化,您也可以在bean的lazy
注释中指定String
@Scope
值:
@Bean
@Scope("lazy")
public MyDependency getMyDependency(){
...
}
或者更好,您可以使用@Lazy
注释来注释bean声明或所有配置(如果您希望所有bean都是延迟初始化的)。
对于特定的bean:
@Bean
@Lazy
public MyDependency getMyDependency(){
...
}
对于配置的所有bean:
@Lazy
@Configuration
public class MyDependencyConfig {
...
}