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

如何从配置文件动态设置@JmsListener的destination属性

解决@JmsListener从application.properties配置destination的问题

嘿,我来帮你搞定这个问题~你当前的写法会触发编译错误,因为@JmsListener的destination参数要求是编译时常量,而queueProperties.getQueueName()是运行时才能计算出来的值,编译器根本没法识别它。下面给你两种靠谱的解决方案:

方案一:直接用SpEL读取配置文件(最简单)

这种方式不需要额外的配置类,直接通过SpEL表达式${配置键}读取application.properties里的值:

第一步:在application.properties中添加配置

# 自定义你的队列名称,前缀可以根据业务调整
app.jms.target-queue=my-business-queue

第二步:修改ListenerService代码

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;
import javax.jms.JMSException;

@Service
public class ListenerService {
    // 推荐用SLF4J的LoggerFactory,比原生Logger更灵活
    private static final Logger log = LoggerFactory.getLogger(ListenerService.class);

    // 用${app.jms.target-queue}直接绑定配置文件中的值
    @JmsListener(destination = "${app.jms.target-queue}")
    public void listenQueue(String requestJSON) throws JMSException {
        log.info("Received message: {}", requestJSON);
    }
}

方案二:通过配置类封装+SpEL引用Bean属性

如果你需要把多个JMS相关配置封装到一个类里管理,这种方式更合适:

第一步:创建配置类绑定配置项

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

// 绑定前缀为app.jms的配置项
@ConfigurationProperties(prefix = "app.jms")
@Component
public class QueueProperties {
    private String queueName;

    // 必须提供getter(SpEL需要通过getter读取属性)
    public String getQueueName() {
        return queueName;
    }

    // 提供setter让Spring自动注入配置值
    public void setQueueName(String queueName) {
        this.queueName = queueName;
    }
}

第二步:在application.properties中添加配置

app.jms.queue-name=my-business-queue

第三步:修改ListenerService代码

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;
import javax.jms.JMSException;

@Service
public class ListenerService {
    private static final Logger log = LoggerFactory.getLogger(ListenerService.class);
    private final QueueProperties queueProperties;

    // Spring 4.3+版本可以省略@Autowired,构造函数注入是最佳实践
    public ListenerService(QueueProperties queueProperties) {
        this.queueProperties = queueProperties;
    }

    // 用#{queueProperties.queueName}引用配置Bean的属性
    @JmsListener(destination = "#{queueProperties.queueName}")
    public void listenQueue(String requestJSON) throws JMSException {
        log.info("Received ...");
    }
}

补充说明

  • 为什么原来的写法不行?因为Java注解的参数必须是编译时常量(比如字符串字面量、static final常量),而调用对象方法是运行时行为,编译器无法提前确定它的值,所以会报错。
  • 优先选方案一,除非你有多个相关配置需要统一管理,再用方案二。

内容的提问来源于stack exchange,提问作者JaChNo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:21:54