以下测试是在springboot2.4.x版本中验证
- 一个配置类中注入两个相同名称的实例
结论:同一个配置类中有了相同名称的实例,第一个会成功执行,第二个不会执行,程序不会报错。
//Worker是自定义的bean,在MyConfig中注入两个相同的实例名的worker,
//最终会只有worker1是成功注入,worker2不会执行,所以没有注入
@Configuration
public class MyConfig {
@Bean("worker")
public Worker getWorker1() {
System.out.println("worker1"); //成功打印
return new Worker("worker1");
}
@Bean("worker")
public Worker getWorker2() {
System.out.println("worker2"); //没有打印
return new Worker("worker2");
}
}
- 在不同的配置类中注入名称相同的实例
结论: 不同的配置类中注入名称相同的实例会报错,容器中已经有相同名称的实例对象。
@Configuration
public class MyConfig {
@Bean("worker")
public Worker getWorker1() {
System.out.println("worker1");
return new Worker("worker1");
}
}
@Configuration
public class MyConfig2 {
@Bean("worker")
public Worker getWorker2() {
System.out.println("worker2");
return new Worker("worker2");
}
}
打印台输出的报错结果:
Description:
The bean 'worker', defined in class path resource [xxx/MyConfig2.class], could not be registered.
A bean with that name has already been defined in class path resource [xxx/MyConfig.class] and overriding is disabled.
- 在一个配置类中获取已经注入的实例对象
注意:我在执行的时候,控制台报出循环依赖的错误,但是后面又正常了,这种情况原因未知,可能是编译器的问题,以后再探究。
//@Bean后面的括号如果没有参数,默认会使用方法名作为bean的名称
@Configuration
public class MyConfig {
@Bean("worker")
public Worker getWorker1() {
System.out.println("worker1");
return new Worker("worker1");
}
/**
@Bean:如果getWorker1中返回的Worker实例名为worker,下面方法不会执行,
因为@Bean没有参数,会使用方法名作为实例名,而容器中已经有了worker的实例,
所以程序不会报错,但是方法不会执行,这种情况和同一个配置类中注入名称相同的实例是一样的。
*/
@Bean
public Worker worker(Worker worker) {
System.out.println(worker);
return new Worker("worker3");
}
/**
@Bean("worker3"):
这种情况下,方法会执行,方法参数获取到的是上面已经注入的worker1,
方法执行完后,容器中Woker的就有两个实例对象。
注意:这种情况是按照类型获取的,如果其他地方还注入了Woker的实例,
此时就会报错,需要添加@Qualifier("xxx")获取指定名称的实例。
*/
@Bean("worker3")
public Worker worker(@Qualifier("worker") Worker worker) {
System.out.println(worker);
return new Worker("worker3");
}
}