面试题------同名Bean会报错吗?结合@Autowired与@Resource详解
本文会详细介绍同名Bean是否会报错,并结合@Autowired与@Resource注解,介绍不同情况下报错原因,以及@Autowired与@Resource的区别
首先同名Bean会报错吗?
分两种情况:
1.在同一配置类/文件中的同名bean
2.在不同配置类/文件中的同名bean
同一配置类/文件中的同名bean
代码
//测试同名bean是否会报错
@Configuration
public class SpringConfigTest {
@Bean(name = "pmAreasTService05")
public PmAreasTService01 pmAreasTService01(){
return new PmAreasTService01();
}
@Bean(name = "pmAreasTService05")
public PmAreasTService02 pmAreasTService02(){
return new PmAreasTService02();
}
}
结论1:同一配置类/文件中的同名bean,在应用程序启动时不会报错。
使用@Autowired注解测试同一配置类/文件中的同名bean
示例代码
//测试同名bean是否会报错
@Component
public class SpringConfigTest02 {
@Autowired
private PmAreasTService01 pmAreasTService01;
@Autowired
private PmAreasTService02 pmAreasTService02;
}
报错异常信息:
Field pmAreasTService02 in com.example.demo.tests.SpringConfigTest02 required a bean of type 'com.example.demo.tests.PmAreasTService02' that could not be found.
原因:首先在同一配置类/文件中的同名bean,项目启动时确实不会报错,但是由于时同名bean,spring在加载完PmAreasTService01之后,就不会在加载PmAreasTService02
而@Autowired注解是根据类型实现依赖注入,因此能够找到PmAreasTService01,但是找不到PmAreasTService02
结论2:同一配置类/文件中的同名bean,在应用程序启动时,不会报错,但是在通过@Autowired注解引用第二个Bean时会报错。如果不引用第二个不会报错!
使用@Resource注解测试同一配置类/文件中的同名bean
//测试同名bean是否会报错
@Component
public class SpringConfigTest02 {
@Resource(name = "pmAreasTService05")
private PmAreasTService01 pmAreasTService01;
@Resource(name = "pmAreasTService05")
private PmAreasTService02 pmAreasTService02;
}
报错异常信息:
Error creating bean with name 'springConfigTest02': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException:
Bean named 'pmAreasTService05' is expected to be of type 'com.example.demo.tests.PmAreasTService02' but was actually of type 'com.example.demo.tests.PmAreasTService01'
一样报错,但是错误原因不同。
是因为@Resource根据名字实现依赖注入,此时对于PmAreasTService02 来说能够找到所需要的bean。
但是此时的bean类型是PmAreasTService01,类型不匹配。
至于为什么类型是PmAreasTService01,上文写过不再赘述。
附加如果beanName找不到,@Rescource会报错吗?
示例:
@Configuration
public class SpringConfigTest {
@Bean(name = "pmAreasTService05")
public PmAreasTService01 pmAreasTService01(){
return new PmAreasTService01();
}
@Bean(name = "pmAreasTService06")
public PmAreasTService02 pmAreasTService02(){
return new PmAreasTService02();
}
}
--------------------
@Resource
private PmAreasTService01 pmAreasTService01;
@Resource
private PmAreasTService02 pmAreasTService02;
答案:不会报错,因为@Resource注解会先根据名字匹配bean,不过找不到bean,则会再根据类型匹配。此时则都能够找到。
不同配置类/文件中的同名bean
示例代码:
@Configuration
public class SpringConfigTest {
@Bean(name = "pmAreasTService05")
public PmAreasTService01 pmAreasTService01(){
return new PmAreasTService01();
}
}
----------------------
@Configuration
public class SpringConfigTest03 {
@Bean(name = "pmAreasTService05")
public PmAreasTService02 pmAreasTService02(){
return new PmAreasTService02();
}
}
启动报错异常信息:
The bean 'pmAreasTService05', defined in class path resource [com/example/demo/tests/SpringConfigTest03.class], could not be registered.
A bean with that name has already been defined in class path resource [com/example/demo/tests/SpringConfigTest.class] and overriding is disabled.
结论:不同配置类/文件中的同名bean,启动时会出现同名bean冲突,导致启动失败
如有疏漏请指出