如何使用Spring Boot配置嵌入式ActiveMQ Broker URL

我按照一个简单的例子来设置和运行带有Spring Boot的嵌入式ActiveMQ(版本1.4.X)。 这是示例https://spring.io/guides/gs/messaging-jms/的链接

我的课程结构如下:

@SpringBootApplication @EnableJms public class Application { @Autowired ConfigurableApplicationContext context; @Bean JmsListenerContainerFactory myJmsContainerFactory(ConnectionFactory connectionFactory) { SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); return factory; } @JmsListener(destination = "mailbox-destination", containerFactory = "myJmsContainerFactory") public void receiveMessage(String message) { System.out.println("Message received: " + message); context.close(); } public static void main(String[] args) throws Exception { FileSystemUtils.deleteRecursively(new File("active-data")); ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); JmsTemplate template = context.getBean(JmsTemplate.class); MessageCreator messageCreator = new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage("Test"); } }; template.send("mailbox-destination", messageCreator); } } 

和build.gradle如下:

 apply plugin: 'java' apply plugin: 'maven' group = 'jms.activemq' version = '0.0.1-SNAPSHOT' description = """jms.activemq""" sourceCompatibility = 1.5 targetCompatibility = 1.5 repositories { maven { url "http://repo.maven.apache.org/maven2" } } dependencies { compile group: 'org.springframework.boot', name: 'spring-boot-starter-activemq', version:'1.4.0.RELEASE' testCompile(group: 'org.springframework.boot', name: 'spring-boot-starter-test', version:'1.4.0.RELEASE') { exclude(module: 'commons-logging') } } 

到目前为止一切运行良好(只要我将application.properties留空),但如果我尝试通过向application.properties文件添加以下内容来配置代理URL(以便远程客户端可以连接):

 spring.activemq.broker-url=tcp://localhost:61616 spring.activemq.user=admin spring.activemq.password=admin 

我得到一个例外:

 2016-08-03 12:46:00.938 WARN 88180 --- [ main] scaAnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.jms.config.internalJmsListenerEndpointRegistry'; nested exception is org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: java.net.ConnectException: Connection refused: connect 2016-08-03 12:46:00.939 INFO 88180 --- [ main] osjeaAnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown 2016-08-03 12:46:00.945 INFO 88180 --- [ main] utoConfigurationReportLoggingInitializer : org.springframework.context.ApplicationContextException: Failed to start bean 'org.springframework.jms.config.internalJmsListenerEndpointRegistry'; nested exception is org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: java.net.ConnectException: Connection refused: connect at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:176) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:874) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] at jms.activemq.Application.main(Application.java:37) [main/:na] Caused by: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: java.net.ConnectException: Connection refused: connect at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.listener.AbstractJmsListeningContainer.start(AbstractJmsListeningContainer.java:273) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.config.JmsListenerEndpointRegistry.startIfNecessary(JmsListenerEndpointRegistry.java:243) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.config.JmsListenerEndpointRegistry.start(JmsListenerEndpointRegistry.java:206) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE] ... 12 common frames omitted Caused by: javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: java.net.ConnectException: Connection refused: connect at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:373) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:303) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:243) ~[activemq-client-5.13.4.jar:5.13.4] at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:180) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.listener.AbstractJmsListeningContainer.createSharedConnection(AbstractJmsListeningContainer.java:413) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.listener.AbstractJmsListeningContainer.establishSharedConnection(AbstractJmsListeningContainer.java:381) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.listener.AbstractJmsListeningContainer.doStart(AbstractJmsListeningContainer.java:285) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.listener.SimpleMessageListenerContainer.doStart(SimpleMessageListenerContainer.java:210) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] at org.springframework.jms.listener.AbstractJmsListeningContainer.start(AbstractJmsListeningContainer.java:270) ~[spring-jms-4.3.2.RELEASE.jar:4.3.2.RELEASE] ... 15 common frames omitted Caused by: java.net.ConnectException: Connection refused: connect at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.8.0_92] at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) ~[na:1.8.0_92] at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_92] at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_92] at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_92] at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_92] at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_92] at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_92] at org.apache.activemq.transport.tcp.TcpTransport.connect(TcpTransport.java:525) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.transport.tcp.TcpTransport.doStart(TcpTransport.java:488) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.util.ServiceSupport.start(ServiceSupport.java:55) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.transport.AbstractInactivityMonitor.start(AbstractInactivityMonitor.java:168) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.transport.InactivityMonitor.start(InactivityMonitor.java:52) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.transport.WireFormatNegotiator.start(WireFormatNegotiator.java:72) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.transport.TransportFilter.start(TransportFilter.java:58) ~[activemq-client-5.13.4.jar:5.13.4] at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:353) ~[activemq-client-5.13.4.jar:5.13.4] ... 23 common frames omitted 

我查看了几个链接,仍然无法确定导致问题的原因。 真的很感激一些有用的见解或材料。

我最初的想法是Spring Boot将读取这些值并使用它们来配置ActiveMQ代理,但看起来它使用这些值来连接代理(已经配置了不同设置的代理)。 如何更改代理配置,以便外部客户端(不使用与代理相同的JVM运行)可以使用tcp:// localhost:61616访问代理

更新:

我已经按照其中一种方法嵌入了此处列出的代理,并且能够使用所需的URL嵌入代理并能够连接到它。 然而,似乎我最终有两个经纪人,因为看起来Spring Boot仍然继续创建一个像以前一样。

基本上,我只是在调用SpringApplication.run(Application.class,args)之前添加这段代码并在main方法的开头添加;

 BrokerService broker = new BrokerService(); broker.addConnector("tcp://localhost:61617"); broker.setPersistent(false); broker.start(); 

感觉不对,有两个代理实例(我相信)正在运行。

1)这是嵌入经纪人的正确方法吗?

2)如果是这样,我如何阻止Spring Boot启动另一个? (无需删除spring-boot-starter-activemq依赖项)。

提前致谢。

我相信在玩了一段时间之后,我想出了这个。 我认为有两个实例正在运行,因为我正在尝试创建与DEFAULT嵌入式代理的连接(试图弄清楚它是否已创建/存在),如下所示:

 ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false"); 

但显然Spring Boot数字并不存在并且当时创建了它。

因此,为了只运行我创建的实例,我需要做的就是提供我在application.properties文件中创建实例(在本例中为tcp://localhost:61616 )时添加到连接器的URL,如下所示

 spring.activemq.broker-url=tcp://localhost:61616 

和Spring Boot将连接到此实例,而不是创建另一个实例。 如果在属性文件中没有上述条目(或者如果您尝试使用vm:// localhost连接到嵌入式实例?…就像我上面所做的那样),Spring Boot将继续为您实例化一个。

我也在文档中读到了这个:

Spring Boot还可以在检测到ActiveMQ在类路径上可用时配置ConnectionFactory。 如果代理存在,则会自动启动并配置嵌入式代理(只要通过配置未指定代理URL)。

但在我看来,它并没有很明确地说明(但确实让我想到了正确的方向)。

如果你有不同的发现或我的结论不对,请告诉我们。 谢谢!!!