Spring Profile配置同类型多Bean启动报匹配冲突如何解决?
问题根因
你遇到的多Bean匹配错误核心有两个原因:
- 你使用的dynamodb spring starter本身会自动注册一个默认的
DynamoDBMapperConfig类型Bean,你之前配置的@Profile仅保证自定义的两个Bean不会同时加载,但没有屏蔽starter的默认Bean,同一激活Profile下会同时存在默认Bean和自定义Bean,因此匹配到多个候选。 - 你之前添加@Primary无效也是因为默认Bean同时存在,没有形成唯一的优先注入候选。
修复方案
- 方案1:屏蔽starter默认自动配置
在启动类的@SpringBootApplication注解中添加排除规则,关闭DynamoDBMapperConfig的自动装配:
配置后Spring上下文只会存在你按Profile定义的唯一自定义@SpringBootApplication(exclude = DynamoDBMapperAutoConfiguration.class)DynamoDBMapperConfigBean,第三方组件会正常注入该实例。 - 方案2:用自定义Bean覆盖starter默认Bean
starter默认注册的DynamoDBMapperConfigBean名称为dynamoDBMapperConfig,你可以通过@Bean的name属性显式指定自定义Bean的名称和默认名称一致,Spring会自动用你定义的Bean覆盖默认实例:
该方案不需要关闭自动配置,同一激活Profile下只会存在一个符合要求的Bean,不会出现冲突。@Configuration public class Config { @Bean(name = "dynamoDBMapperConfig") @Profile("!dev") DynamoDBMapperConfig nonDevConfig(){ return new DynamoDBMapperConfig.Builder().build(); } @Bean(name = "dynamoDBMapperConfig") @Profile("dev") DynamoDBMapperConfig devConfig(){ return new DynamoDBMapperConfig.Builder().build(); } } - 方案3:保留多实例场景的处理
如果你确实需要在上下文同时保留两个自定义的DynamoDBMapperConfig实例,先执行方案1关闭starter默认自动配置,再给供第三方组件使用的Bean添加@Primary注解,你自己的业务代码中可以通过@Qualifier指定Bean名称注入另一个实例:@Configuration public class Config { @Bean @Profile("!dev") @Primary DynamoDBMapperConfig primaryConfig(){ return new DynamoDBMapperConfig.Builder().build(); } @Bean DynamoDBMapperConfig secondaryConfig(){ return new DynamoDBMapperConfig.Builder().build(); } }
内容的提问来源于stack exchange,提问作者Nikita
相关产品推荐
相关产品推荐

