跳转到内容

Spring @Bean 命名机制


@Configuration 配置类中,@Bean 注解的方法返回值会被注册为 Spring 容器中的一个 Bean。默认情况下,方法名就是该 Bean 的唯一 ID。

@Bean
public Queue queueFanoutA() {
return new Queue("camellia.fanout.queueA");
}
// 注册后 Bean ID = "queueFanoutA"

当容器中存在多个相同类型的 Bean 时,按类型注入会产生歧义,需要用 @Qualifier 通过 Bean ID 指定注入哪一个:

@Bean
public Binding bindFanoutA(@Qualifier("queueFanoutA") Queue queue,
FanoutExchange exchange) {
return BindingBuilder.bind(queue).to(exchange);
}

通过 @Beanname(或等价的 value)属性可以覆盖默认的方法名:

@Bean(name = "queueA")
public Queue queueFanoutA() {
return new Queue("camellia.fanout.queueA");
}
// 注册后 Bean ID = "queueA",方法名 queueFanoutA 不再生效

此时 @Qualifier 也需要同步修改:

@Bean
public Binding bindFanoutA(@Qualifier("queueA") Queue queue,
FanoutExchange exchange) {
return BindingBuilder.bind(queue).to(exchange);
}

name 属性还支持传入字符串数组,为同一个 Bean 设置多个别名:

@Bean(name = {"queueA", "fanoutQueueA"})
public Queue queueFanoutA() {
return new Queue("camellia.fanout.queueA");
}
// queueA 和 fanoutQueueA 都能找到这个 Bean

同一容器中 Bean ID 必须唯一。若两个 @Bean 方法产生相同名称,Spring 启动时会抛出:

BeanDefinitionStoreException:
Invalid bean definition with name 'xxx' ... already registered

常见的冲突场景:

// ❌ 两个方法名相同,Bean ID 重复
@Bean
public Queue queue() { return new Queue("queueA"); }
@Bean
public Queue queue() { return new Queue("queueB"); } // 编译直接报错
// ❌ 方法名不同,但手动指定了相同 name
@Bean(name = "myQueue")
public Queue queueA() { return new Queue("queueA"); }
@Bean(name = "myQueue") // 与上方冲突
public Queue queueB() { return new Queue("queueB"); }

两种注册 Bean 的方式在命名规则上略有不同:

注册方式默认 Bean 名称自定义方式
@Bean方法名(完整,不转驼峰)@Bean(name = "xxx")
@Component 系列类名首字母小写@Component("xxx")
// @Bean:Bean ID = "queueFanoutA"(方法名原样)
@Bean
public Queue queueFanoutA() { ... }
// @Component:Bean ID = "userService"(类名首字母小写)
@Component
public class UserService { ... }