同名Bean调用问题:@Primary注解无效时如何调用第二个Bean?
问题分析与解决方案
你遇到的核心问题是:同名Bean注册时,Spring默认保留先定义的实例,且@Primary注解在此场景无效——因为@Primary仅用于同类型不同名Bean的默认注入选择,当Bean名称重复时,容器只会保留一个实例,@Primary没有生效的空间。
解决方案1:关闭配置类代理,让后定义的Bean覆盖先定义的
Spring默认会对@Configuration类进行CGLIB代理(proxyBeanMethods=true),这种机制可能阻止后定义的同名Bean覆盖先定义的。关闭代理后,每个@Bean方法都会被执行,后定义的Bean会覆盖先定义的同名实例。
修改配置类:
package com.springdemo.learnspring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; record Person(String name, int age) {} @Configuration(proxyBeanMethods = false) public class HelloWorldConfiguration { @Bean(name = "GetPerson") public Person person1() { return new Person("Person", 24); } @Bean(name = "GetPerson") public Person person2() { return new Person("Person2", 21); } }
运行主类后,输出会变为:Person[name=Person2, age=21]。
解决方案2:使用不同Bean名称(规范做法)
避免同名Bean是更规范的开发方式,你可以给两个Bean设置不同名称,配合@Primary或直接按名称调用第二个Bean。
修改配置类
package com.springdemo.learnspring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; record Person(String name, int age) {} @Configuration public class HelloWorldConfiguration { @Bean(name = "person1") public Person person1() { return new Person("Person", 24); } @Bean(name = "person2") @Primary public Person person2() { return new Person("Person2", 21); } }
主类调用方式
- 按类型获取(自动选择
@Primary标注的第二个Bean):System.out.println(context.getBean(Person.class)); - 直接按名称获取第二个Bean:
System.out.println(context.getBean("person2"));
为何@Primary之前未生效?
@Primary的作用是当容器中存在多个同类型不同名的Bean时,指定默认注入的实例。但你之前的代码中两个Bean名称完全相同,Spring在注册时只会保留先定义的那个,第二个Bean根本不会被注册到容器中,因此@Primary没有生效的场景。
内容的提问来源于stack exchange,提问作者Subhani
相关产品推荐
相关产品推荐

