使用传入值为@ JmsListener的目标参数

时间:2016-08-10 00:03:34

标签: java spring-boot spring-jms

有没有特定的方法来实现这一目标?我试图在这里找到一个解决方案,但找不到我需要的东西。我有一个Spring Boot应用程序,它将从命令行接受多个参数。有问题的参数是队列名称(即目的地)。它可以是我们众多队列中的几个之一。 JmsListener的格式为

@JmsListener(destination="dest_goes_here")
public void processOrder(Message message){. . .}

我有一个基本上看起来像这样的课程

 public class Arguments {
 private static queue
 private static antoherArg
 :
 :
getters and setters
 }

我想说的是destination = Arguments.getQueue(),但似乎destination只能是static final变量?我假设这是因为错误提供了一个小工具提示,暗示了这一点。

我还测试了它,因为我还有另一个名为Constants的类,obvioulsy包含常量,如果我将队列名称硬编码为public static final String QUEUE = "MyQ";,那么说destination = Constants.QUEUE就可以了接着就,随即。

所以我假设我可以在我的监听器类private static final String QUEUE = Arguments.getQueue();中做这样的事情但是它也不喜欢这样。唉,我很难过。

如果有人愿意分享知识,那么真的有两个问题。 @JmsListener为什么destination设置为我的第二个解决方案,但不是第一个和最后一个解决方案?

然后主要问题(我更喜欢你回答第一个)是,我可以利用什么策略将目标设置为源自命令行的变量(即是动态的)?

编辑:为了澄清,我无法将值保留在Constants类中,因为该值将来自命令行,需要传递给JmsListener类以用作destination }。

1 个答案:

答案 0 :(得分:3)

这就是Java的工作原理,destination必须是编译时常量表达式,而函数调用不算是一个。看看the official language specification for more details编辑:您还可以查看this answer

就你的第二个(也是更重要的)问题而言,我有几个建议。

首先,您可以从配置属性中读取队列名称,如下所示:destination="${jms.queue.name1}"其中jms.queue.name1是您的配置属性。然后,由于您使用的是Spring Boot,因此可以使用命令行参数覆盖配置属性(请参阅externalized configuration documentation for more details)。这样,您就可以在运行时指定队列名称,方法是将其作为命令行参数传递,如--jms.queue.name1=foo

其次,您可以使用programmatic listener registration,如下所示:

@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {

    @Override
    public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
        SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
        endpoint.setId("myJmsEndpoint");
        endpoint.setDestination(Arguments.getQueue());
        endpoint.setMessageListener(message -> {
            // processing
        });
        registrar.registerEndpoint(endpoint);
    }
}