Spring Boot 2.0M7中@Profile多配置逻辑失效问题求助
问题分析与解决方案
首先明确:Spring Boot 2.x(包括你用的2.0M7)的@Profile逻辑没有本质变更,你的问题出在对Profile表达式的逻辑关系理解错误上。
核心问题:Profile数组的逻辑是OR,不是AND
你修改后的代码中:
@Profile({"!test","!dev"})等价于@Profile("!test || !dev")(逻辑或),意思是「只要不是test,或者不是dev」就满足条件。当你激活testProfile时,!dev是成立的,所以这个条件会被判定为true,sqsConnectionFactory会被加载;- 同时
@Profile({"test","dev"})等价于@Profile("test || dev"),激活test时条件也成立,activeMqConnectionFactory也会被加载。
这样就导致两个ConnectionFactory类型的Bean同时存在,Spring在注入时无法确定选哪一个,从而抛出未解析Bean的异常。
正确的配置方式
你需要用逻辑与的表达式来定义「既不是test也不是dev」的场景,Spring的Profile支持SpEL风格的逻辑运算符:
修正后的代码
@Configuration @EnableJms public class QueueConfig { private static Logger LOG = LoggerFactory.getLogger(QueueConfig.class); // 仅当test和dev都未激活时加载SQ工厂 @Profile("!test & !dev") @Bean public ConnectionFactory sqsConnectionFactory() { LOG.info("using sqs"); return new SQSConnectionFactory(new ProviderConfiguration(), AmazonSQSClientBuilder.standard() .withRegion(Regions.EU_WEST_1) .withCredentials(new DefaultAWSCredentialsProviderChain()) ); } // 激活test或dev时加载ActiveMQ工厂 @Profile("test || dev") @Bean public ConnectionFactory activeMqConnectionFactory() { LOG.info("using activemq"); return new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false"); } @Bean public JmsTemplate defaultJmsTemplate(ConnectionFactory connectionFactory) { return new JmsTemplate(connectionFactory); } @Bean public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setDestinationResolver(new DynamicDestinationResolver()); factory.setConcurrency("3-10"); return factory; } }
逻辑说明
@Profile("!test & !dev"):表示同时满足「不是test」和「不是dev」时加载,也就是非test、非dev的生产类环境;@Profile("test || dev"):表示满足其一即可加载,也就是激活test或dev时都会使用ActiveMQ。
这样修改后,无论激活哪个Profile,只会有一个ConnectionFactory Bean被创建,Spring就能正常注入了。
额外验证建议
你可以在测试类中保持@ActiveProfiles("test"),运行后查看日志,应该只会打印using activemq,不会出现两个工厂的加载日志,同时Bean注入异常也会消失。
内容的提问来源于stack exchange,提问作者Jilles van Gurp
相关产品推荐
相关产品推荐

