如何为两个Spring Bean添加@Qualifier并实现对应Autowired注入?
Hey,我来帮你解决这个Spring Bean区分的问题!你已经找对方向了——@Qualifier就是干这个的,下面我一步步给你讲怎么用,结合你的Kotlin代码来改:
第一步:给每个Bean添加@Qualifier标记
首先,你需要在配置类的两个@Bean方法上分别加上@Qualifier注解,给每个Bean指定一个唯一的标识(比如credentials1和credentials2)。这样Spring就能区分这两个同类型的Credentials Bean了。
修改后的配置类代码:
@Configuration @Slf4j @PropertySources( PropertySource("classpath:application.properties"), PropertySource(value = ["file:\${credentials.config}"]) ) class CredentialsConfig(@Autowired private val env: Environment) { @Bean @Qualifier("credentials1") // 给第一个Bean设置唯一限定符 fun getCredentials(): Credentials? { val user: String = env.getRequiredProperty("user1") val pass: String = env.getRequiredProperty("pass1") return Credentials.info(user, pass) } @Bean @Qualifier("credentials2") // 给第二个Bean设置唯一限定符 fun getCredentials2(): Credentials { val user: String = env.getRequiredProperty("user2") val pass: String = env.getRequiredProperty("pass2") return Credentials.info(user, pass) } }
小提示:你也可以用
@Bean(name = "credentials1")替代@Qualifier,因为Spring会把Bean的name当作默认的Qualifier值,效果是一样的。
第二步:注入时用@Qualifier指定要引用的Bean
接下来,在你需要注入Credentials的地方(比如Service类),通过@Qualifier指定你要注入哪个Bean。这里推荐两种常用的注入方式:
方式1:构造注入(Spring最佳实践)
构造注入更符合依赖注入的设计原则,而且便于测试:
@Service class SomeBusinessService( // 给构造参数加上@Qualifier,指定要注入的Bean标识 @Qualifier("credentials1") private val user1Credentials: Credentials, @Qualifier("credentials2") private val user2Credentials: Credentials ) { fun printCredentials() { println("User1 账号:${user1Credentials.user},密码:${user1Credentials.pass}") println("User2 账号:${user2Credentials.user},密码:${user2Credentials.pass}") } }
方式2:字段注入(适合简单场景)
如果是简单的类,字段注入会更简洁:
@Service class SomeBusinessService { @Autowired @Qualifier("credentials1") // 指定注入第一个Bean lateinit var user1Credentials: Credentials @Autowired @Qualifier("credentials2") // 指定注入第二个Bean lateinit var user2Credentials: Credentials // 业务逻辑... }
进阶技巧:自定义Qualifier注解
如果觉得每次写字符串"credentials1"容易出错,你可以自定义专属的Qualifier注解,让代码更清晰:
首先创建两个自定义注解:
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) @Qualifier annotation class User1Credentials @Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) @Qualifier annotation class User2Credentials
然后修改配置类的Bean:
@Bean @User1Credentials fun getCredentials(): Credentials? { ... } @Bean @User2Credentials fun getCredentials2(): Credentials { ... }
最后注入时直接用自定义注解:
@Service class SomeBusinessService( @User1Credentials private val user1Credentials: Credentials, @User2Credentials private val user2Credentials: Credentials ) { ... }
这样就彻底避免了字符串硬编码的问题,代码可读性也更高!
内容的提问来源于stack exchange,提问作者C96
相关产品推荐
相关产品推荐

