使用 spring 集成自动配置 ActiveMQ
Posted
技术标签:
【中文标题】使用 spring 集成自动配置 ActiveMQ【英文标题】:Autoconfiguration of ActiveMQ with spring integration 【发布时间】:2014-10-01 07:38:31 【问题描述】:在当前版本中,当 Spring Boot 检测到 ActiveMQ 在类路径上可用时,它还可以配置 ConnectionFactory。如果存在代理,则会自动启动和配置嵌入式代理。
在使用 JMSTemplate 时似乎是这样。如果我想使用 spring 集成自动配置,那么不幸的是这不起作用。 ActiveMQ 似乎是在 spring 集成之后配置的。 Spring boot 报告缺少连接工厂的错误。 为此,我正在使用 Spring Boot 版本 1.1.4 和最新版本的 Spring 集成。
我从 spring boot 中得到这个堆栈跟踪:
2014-08-08 09:24:21.050 ERROR 6728 --- [ main]
o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'org.springframework.integration.jms.JmsSendingMessageHandler#0':
Cannot create inner bean '(inner bean)#54930080' of type
[org.springframework.integration.jms.DynamicJmsTemplate] while setting constructor
argument; nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name '(inner bean)#54930080': Cannot resolve reference to
bean 'connectionFactory' while setting bean property 'connectionFactory'; nested
exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean
named 'connectionFactory' is defined
at
org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(
BeanDefinitionValueResolver.java:290)
at
org.springframework.beans.factory.support.BeanDefinitionValueResolver.
resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)
对我来说,在 spring 集成和 jms 模板方面,spring boot 自动配置中的依赖项似乎是不正确的。 标准 JMS 自动配置如下所示:
@ConditionalOnClass(JmsTemplate.class)
@ConditionalOnBean(ConnectionFactory.class)
@EnableConfigurationProperties(JmsProperties.class)
@AutoConfigureAfter( HornetQAutoConfiguration.class,
ActiveMQAutoConfiguration.class )
public class JmsAutoConfiguration
Spring 集成如下所示:
@Configuration
@ConditionalOnClass(EnableIntegration.class)
@AutoConfigureAfter(JmxAutoConfiguration.class)
public class IntegrationAutoConfiguration
对于 spring 集成创建的关于连接工厂和活动 mq 的动态 jms 模板,是否应该至少有某种自动配置。考虑到 spring boot ref docs,我希望使用 jms 进行正确的自动配置以进行 spring 集成?
【问题讨论】:
请进一步描述——不仅仅是“不起作用”;包括配置、堆栈跟踪等。我建议你记录一个 DEBUG 日志;如果您无法从日志中弄清楚,请将其发布在某个地方,我相信有人会提供帮助。 这种情况是您希望手动连接组件的原因 - 以控制“依赖”和启动顺序。不过,我对这个问题没有答案。 你到底在说什么自动配置? 我在我的问题中添加了更多细节,希望它能更清楚我的问题是什么。我可以手动解决这个定义连接工厂bean的问题,但是spring boot应该在参考文档中提到这一点,对于spring集成,jms自动配置和活动mq自动配置不起作用 我不确定 JMX 与此有什么关系。你能在某个地方发布一个重现问题的项目吗? 【参考方案1】:好的 - 明白了。这是一个错误(我认为)。
ActiveMQConnectionFactoryConfiguration 创建一个名为“jmsConnectionFactory”的 bean,但查看您的堆栈跟踪(上图)Spring Integration 正在寻找要命名的 bean:“connectionFactory”
编辑:INT-3941打开
解决方法:
@Configuration
public static class SpringBootVsIntegraionWorkaround
@Autowired
GenericApplicationContext genericApplicationContext;
@PostConstruct
public void init()
genericApplicationContext.registerAlias("jmsConnectionFactory", "connectionFactory");
【讨论】:
ActiveMQConnectionFactoryConfiguration 链接现已失效。 谢谢。结构在 2.0 中发生了变化。我已将链接更新为指向 1.5 分支(我找到它的地方)而不是 master。【参考方案2】:我已经复制了这个问题。这是一个例子:
之前(只是为了显示一切正常):
@SpringBootApplication
public class HelloWorldSiActivemqApplication
public static void main(String[] args)
SpringApplication.run(HelloWorldSiActivemqApplication.class, args);
@Service
public static class SayHelloService
@Autowired
ConnectionFactory connectionFactory;
public void sayHello(String name)
System.out.println("JMS Connection Factory: " + connectionFactory);
System.out.println("## Hello " + name + "!!!" );
@Component
public static class HelloListener
@Autowired
SayHelloService sayHelloService;
@JmsListener(destination="helloJMSQueue")
public void sayHello(String name)
sayHelloService.sayHello(name);
application.properties
spring.activemq.broker-url=tcp://0.0.0.0:61613
spring.activemq.user=admin
spring.activemq.password=password
效果很好。当我通过单元测试访问 JMS 端点时,我得到:
JMS Connection Factory: org.apache.activemq.ActiveMQConnectionFactory@4b137f92
## Hello SayHelloServiceTest!!!
但是,当我介绍 Spring Integration 时:
@ImportResource("classpath*:/spring/si-config.xml")
si-config.xml
<jms:message-driven-channel-adapter id="helloJMSAdapater" destination="helloJMSQueue"
channel="helloChannel"/>
<integration:channel id="helloChannel"/>
..然后重新运行我得到的测试:
No bean named 'connectionFactory' is defined
希望这会有所帮助!
【讨论】:
【参考方案3】:当一个 'connectionFactory' bean 被自动设置时,一个简单的解决方法是使用一个别名来使两者都可用:
<alias name="connectionFactory" alias="jmsConnectionFactory" />
【讨论】:
以上是关于使用 spring 集成自动配置 ActiveMQ的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot学习笔记——Spring Boot与ActiveMQ的集成