使用传入的值作为@JmsListener 的目标参数
Using passed in Value for @JmsListener's destination paramter
有没有具体的方法可以做到这一点?我试图在这里找到解决方案,但找不到我需要的东西。我有一个 Spring 引导应用程序,它将接受来自命令行的多个参数。有问题的参数是队列名称(即目的地)。它可以是我们众多队列中的几个。 JmsListener
的形式是
@JmsListener(destination="dest_goes_here")
public void processOrder(Message message){. . .}
我有一个 class 基本上是这样的
public class Arguments {
private static queue
private static antoherArg
:
:
getters and setters
}
而我想说的是destination = Arguments.getQueue()
,但是好像destination
只能是一个static final
变量?我假设这是因为错误提供了一个暗示这一点的小工具提示。
我也测试了它,因为我还有另一个 class 叫做 Constants
,它显然包含常量,如果我将队列名称硬编码为 public static final String QUEUE = "MyQ";
然后说 destination = Constants.QUEUE
没关系。
所以我假设我可以在我的监听器中做这样的事情 class private static final String QUEUE = Arguments.getQueue();
但它也不喜欢那样。唉,难倒我了。
如果有人愿意分享知识,那么这里真的有两个问题。为什么 @JmsListener
可以将 destination
设置为我的第二个解决方案,而不是第一个和最后一个?
然后是主要问题(我希望您先回答这个问题)是,我可以使用什么策略将目标设置为源自命令行的变量(即动态)?
编辑:澄清一下,我不能将值保留在 Constants
class 中,因为该值将来自命令行,需要传递给 JmsListener class 用作 destination
.
这就是 Java 的工作原理,destination
必须是一个编译时常量表达式,函数调用不被视为一个。看看the official language specification for more details. EDIT: you can also look at this answer.
就你的第二个(也是更重要的)问题而言,我有几个建议给你。
首先,您可以从配置 属性 中读取队列名称,如下所示:destination="${jms.queue.name1}"
其中 jms.queue.name1
是您的配置 属性。然后,由于您正在使用 Spring 启动,您可以使用命令行参数来覆盖您的配置属性(请参阅 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);
}
}
有没有具体的方法可以做到这一点?我试图在这里找到解决方案,但找不到我需要的东西。我有一个 Spring 引导应用程序,它将接受来自命令行的多个参数。有问题的参数是队列名称(即目的地)。它可以是我们众多队列中的几个。 JmsListener
的形式是
@JmsListener(destination="dest_goes_here")
public void processOrder(Message message){. . .}
我有一个 class 基本上是这样的
public class Arguments {
private static queue
private static antoherArg
:
:
getters and setters
}
而我想说的是destination = Arguments.getQueue()
,但是好像destination
只能是一个static final
变量?我假设这是因为错误提供了一个暗示这一点的小工具提示。
我也测试了它,因为我还有另一个 class 叫做 Constants
,它显然包含常量,如果我将队列名称硬编码为 public static final String QUEUE = "MyQ";
然后说 destination = Constants.QUEUE
没关系。
所以我假设我可以在我的监听器中做这样的事情 class private static final String QUEUE = Arguments.getQueue();
但它也不喜欢那样。唉,难倒我了。
如果有人愿意分享知识,那么这里真的有两个问题。为什么 @JmsListener
可以将 destination
设置为我的第二个解决方案,而不是第一个和最后一个?
然后是主要问题(我希望您先回答这个问题)是,我可以使用什么策略将目标设置为源自命令行的变量(即动态)?
编辑:澄清一下,我不能将值保留在 Constants
class 中,因为该值将来自命令行,需要传递给 JmsListener class 用作 destination
.
这就是 Java 的工作原理,destination
必须是一个编译时常量表达式,函数调用不被视为一个。看看the official language specification for more details. EDIT: you can also look at this answer.
就你的第二个(也是更重要的)问题而言,我有几个建议给你。
首先,您可以从配置 属性 中读取队列名称,如下所示:destination="${jms.queue.name1}"
其中 jms.queue.name1
是您的配置 属性。然后,由于您正在使用 Spring 启动,您可以使用命令行参数来覆盖您的配置属性(请参阅 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);
}
}