为什么Spring Boot会创建相同类型的bean,而不管@Primary注释是什么?

jbw*_*bwt 0 java spring spring-boot

我有一个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);
}
}
Run Code Online (Sandbox Code Playgroud)

并在我的代码中的其他地方:

@Autowired
MyDependency foo
Run Code Online (Sandbox Code Playgroud)

为什么在应用程序上下文启动时,我的控制台打印出来

getMyDependency

getMyDependency2

什么时候只使用getMyDependency()中的bean?我正在使用spring boot-1.5.1.RELEASE

谢谢你,杰森

dav*_*xxx 6

Spring配置在Spring上下文启动时实例化并加载Spring容器中的所有声明和必需的bean.

因此,即使您不使用配置中定义的所有bean,@Bean也会调用配置中注释的方法.

@Primary标注有另一个目标.

它表示当多个候选者有资格自动装配单值依赖时,应该优先考虑bean.如果候选者中只存在一个"主"bean,则它将是自动装配的值.

@Qualifier当你有多个候选bean时,它只是一种不系统地指定注释的方法.

例如,在您的情况下,两个bean之一被指定为primary :

@Bean
@Primary
public MyDependency getMyDependency(){
    System.out.println("getMyDependency");
    return Mockito.mock(MyDependency.class);
}
Run Code Online (Sandbox Code Playgroud)

您不需要指定限定符"getMyDependency"来注入指定的限定符primary:

@Autowired
@Qualifier("getMyDependency")
MyDependency foo;
Run Code Online (Sandbox Code Playgroud)

你可以直接这样做:

@Autowired
MyDependency foo;
Run Code Online (Sandbox Code Playgroud)

而对于第二个未指定为bean的bean @Primary:

@Bean
public MyDependency getMyDependency2(){
    System.out.println("getMyDependency2");
    return Mockito.mock(MyDependency.class);
}
Run Code Online (Sandbox Code Playgroud)

@Qualifier当你想要注入它时,你必须指定清除歧义:

@Autowired
@Qualifier("getMyDependency2")
MyDependency foo;
Run Code Online (Sandbox Code Playgroud)

建议不要以懒惰方式加载bean,因为它会延迟配置错误的捕获.所以,它默认是急切的.

您在评论中提供的链接中有更多详细信息.
现在,如果要阻止此默认行为并为bean定义延迟初始化,您可以选择在bean lazy String@Scope注释中指定值:

@Bean 
@Scope("lazy")
public MyDependency getMyDependency(){
  ...
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是,您可以使用注释来注释bean声明或所有配置(如果您希望所有bean都是惰性初始化的)@Lazy.

对于特定的bean:

@Bean 
@Lazy
public MyDependency getMyDependency(){
   ...
}
Run Code Online (Sandbox Code Playgroud)

对于配置的所有bean:

@Lazy
@Configuration
public class MyDependencyConfig {
   ...
}
Run Code Online (Sandbox Code Playgroud)