使用注解与XML配置定义同类型不同名称Bean的Spring疑问
Spring 同一类多Bean定义的疑问解答
场景说明:通过@Component注解创建名为tennisCoach的TennisCoach Bean,同时通过XML配置创建名为myCoach的同类型Bean,获取两个Bean实例时内存地址不同,针对该场景解答以下疑问:
1. Spring为何允许创建这两个对象?
Spring中Bean的唯一标识是Bean名称(id/name),而非Bean对应的类。只要两个Bean定义的名称不重复,哪怕它们指向同一个类,Spring也会将其视为两个独立的Bean定义,分别实例化并管理。这里tennisCoach和myCoach是两个不同的Bean名称,因此Spring允许创建这两个独立的对象。
2. 为何不会因同一类通过注解和XML重复定义Bean而报错?
Spring的Bean冲突校验逻辑是基于Bean名称的:只有当两个不同的Bean定义(不管是注解还是XML方式)使用了完全相同的名称时,才会抛出Bean定义冲突的异常。
本场景中,注解生成的Bean默认名称是类名首字母小写的tennisCoach,XML配置的Bean名称是myCoach,二者名称不同,因此不会触发冲突报错。
3. 此时Spring是按原型作用域创建对象吗?
不是。两个Bean都使用了Spring默认的单例(singleton)作用域:
- 对于
tennisCoach这个Bean定义,每次获取都会返回同一个实例; - 对于
myCoach这个Bean定义,每次获取也会返回同一个实例;
只是这两个Bean定义各自维护了一个独立的单例实例,所以它们的内存地址不同。如果是原型作用域,每次调用getBean()都会生成新的实例,而本场景中多次获取tennisCoach只会得到同一个地址的对象,多次获取myCoach也是如此。
相关代码示例
Java调用代码:
Coach coach = context.getBean("tennisCoach", Coach.class); Coach coach2 = context.getBean("myCoach", Coach.class); System.out.println(coach); // output: demo.TennisCoach@451001e5 System.out.println(coach2); // output: demo.TennisCoach@2b40ff9c
XML配置文件:
<bean id="myCoach" class="demo.TennisCoach"></bean>
TennisCoach类代码:
@Component public class TennisCoach implements Coach {...}
内容的提问来源于stack exchange,提问作者EmelK
相关产品推荐
相关产品推荐

