将JMS Queue XML配置转换为Java配置

时间:2016-09-15 15:24:07

标签: spring-integration

为了学习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: {}

2 个答案:

答案 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;
}