为了学习spring集成,我一直在尝试创建一个简单,有弹性的日志处理器。我也想坚持使用java配置方法。
我在翻译现有的XML配置时遇到了困难,主要原因是一般来说这是一个很新的。
在a question on the spring forums中,Gary Russell使用带有简单XML配置的发布 - 订阅+ JMS模型提出了类似的解决方案。
我一直试图将他的建议翻译成Java配置,但我被卡住了。即我不确定用于出站通道适配器,服务激活器或如何正确设置消息顺序的正确实体。
这是Gary的XML配置:
<int-file:inbound-channel-adapter id="dispatcher"
directory="spool"
channel="fileChannel">
<int:poller fixed-delay="2000">
<int:transactional/>
</int:poller>
</int-file:inbound-channel-adapter>
<int:channel id="fileChannel" />
<int-file:file-to-string-transformer input-channel="fileChannel" output-channel="dispatchChannel" />
<int:publish-subscribe-channel id="dispatchChannel" />
<int-jms:outbound-channel-adapter id="dispatcherJms" channel="dispatchChannel" order="1"
connection-factory="connectionFactory"
destination="dispatcher.queue" />
<!-- If JMS Send was successful, remove the file (within the transaction)-->
<int:service-activator input-channel="dispatchChannel" order="2"
output-channel="nullChannel"
expression="headers.file_originalFile.delete()">
<bean id="transactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
更新
根据以下评论,我更新了java配置。
但是,我仍然收到错误,很可能不理解实体之间的流量和联系,但原来的问题已经得到解答。
@Bean
@Transactional
@InboundChannelAdapter(channel = "dispatchChannel", poller = @Poller(fixedDelay = "2000"))
public MessageSource<?> dispatcher() {
CompositeFileListFilter<File> filters = new CompositeFileListFilter<>();
filters.addFilter(new SimplePatternFileListFilter(sourceFilenamePattern));
//filters.addFilter(persistentFilter());
FileReadingMessageSource source = new FileReadingMessageSource();
source.setAutoCreateDirectory(true);
source.setDirectory(new File(sourceDirectory));
source.setFilter(filters);
return source;
}
@Bean
public MessageChannel fileChannel() {
return new DirectChannel();
}
@Bean
public PublishSubscribeChannel dispatchChannel() {
return new PublishSubscribeChannel();
}
@Autowired
JmsTemplate jmsTemplate;
@Autowired
ConnectionFactory connectionFactory;
@Bean
@Order(1)
@ServiceActivator(inputChannel = "dispatchChannel")
public MessageHandler dispatcherJmsOutboundChannelAdapter(Message<File> message) {
JmsSendingMessageHandler handler = new JmsSendingMessageHandler(jmsTemplate);
handler.setDestinationName("dispatcher.queue");
return handler;
}
@Bean
@Order(2)
@ServiceActivator(inputChannel = "dispatchChannel")
public void removeFile(Message<?> message) {
//message.getHeaders().get(FileHeaders.ORIGINAL_FILE, File.class).delete();
log.info("delete");
}
@Bean
public JmsTransactionManager transactionManager(ConnectionFactory connectionFactory) {
return new JmsTransactionManager(connectionFactory);
}
我使用的是弹簧启动和几个启动器组件,例如activemq。我已经为JmsListenerContainerFactory和@JmsListener添加了@Bean,但我不确定这些是否真的有必要。
在将@EnableJms添加到我的配置文件以及@Autowiring jmstemplate和connectionfactory之前,我无法运行任何内容。
运行时,我现在收到的错误是:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [org.springframework.messaging.Message] found for dependency
[org.springframework.messaging.Message<?>]:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {}
答案 0 :(得分:1)
这一个
<int:service-activator input-channel="dispatchChannel" order="2"
output-channel="nullChannel"
expression="headers.file_originalFile.delete()">
Java中的非常简单:
@ServiceActivator(inputChannel = "dispatchChannel")
public void removeFile(Message<?> message) {
message.getHeaders().get(FileHeaders.ORIGINAL_FILE, File.class).delete();
}
和
<int-jms:outbound-channel-adapter>
被翻译成:
@Bean
@ServiceActivator(inputChannel = "dispatchChannel")
public MessageHandler dispatcherJmsOutboundChannelAdapter() {
JmsSendingMessageHandler handler =
new JmsSendingMessageHandler(new JmsTemplate(this.connectionFactory));
handler.setDestinationName("dispatcher.queue");
return handler;
}
请注意Reference Manual中的这一段。
答案 1 :(得分:0)
最后一块拼图游戏是FileWritingMessageHandler
@Bean
public FileWritingMessageHandler fileWritingMessageHandler() {
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("headers.file_originalFile.delete()");
FileWritingMessageHandler fileWritingMessageHandler = new FileWritingMessageHandler(expression);
fileWritingMessageHandler.setOutputChannel(new NullChannel());
fileWritingMessageHandler.setDeleteSourceFiles(true);
return fileWritingMessageHandler;
}