You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.0M7中@Profile多配置逻辑失效问题求助

问题分析与解决方案

首先明确:Spring Boot 2.x(包括你用的2.0M7)的@Profile逻辑没有本质变更,你的问题出在对Profile表达式的逻辑关系理解错误上。

核心问题:Profile数组的逻辑是OR,不是AND

你修改后的代码中:

  • @Profile({"!test","!dev"}) 等价于 @Profile("!test || !dev")(逻辑或),意思是「只要不是test,或者不是dev」就满足条件。当你激活test Profile时,!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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:43:04