我跟随了一个简单的示例,该示例使用Spring Boot(版本1.4.X)设置和运行嵌入式ActiveMQ。这是指向示例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); } }
并如下所示构建:
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] s.c.a.AnnotationConfigApplicationContext : 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] o.s.j.e.a.AnnotationMBeanExporter : 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);之前在主方法的开头添加这段代码。
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认为当时不存在并创建它。
因此,为了只运行我创建的实例,我要做的就是提供一个tcp://localhost:61616在application.properties文件中创建实例时(在本例中)添加到连接器的URL ,如下所示
tcp://localhost:61616
application.properties
spring.activemq.broker-url=tcp://localhost:61616
然后Spring Boot将连接到该实例,而不创建另一个实例。在属性文件中缺少上述条目的情况下(或者,如果您像我上面那样尝试使用vm:// localhost?…连接到嵌入式实例),Spring Boot将继续为您实例化一个实例。
我也确实在文档中阅读了此内容:
当Spring Boot检测到ActiveMQ在类路径上可用时,它也可以配置ConnectionFactory。如果存在代理,则将自动启动并配置嵌入式代理(只要未通过配置指定代理URL)。
但是在我看来,它并没有很好地阐明(但是确实让我思考了正确的方向)。
请告诉我们您是否有不同的发现或我的结论是否正确。谢谢!!!