2016-09-15 12 views
1

バネの統合を学ぶために、私はシンプルで復元力の高いログプロセッサを作成しようとしていました。私はまた、Javaの設定方法を採用したいと思っています。JMSキューのXML設定をJavaの設定に変換する

私は既存のXML構成を翻訳するのが難しい状況にありました。これは主に一般的な春の新機能のためです。

a question on the spring forums Gary Russellは、単純なXML設定のpublish-subscribe + JMSモデルを使用して同様の解決策を提示しました。

私は彼の提案をJava設定に変換しようとしていましたが、固まっています。つまり、outbound-channel-adapter、service-activator、またはメッセージの順序を適切に設定するために使用する適切なエンティティについてはわかりません。ここで

はゲイリーのXML設定ファイルです:私はJavaの設定を更新した以下のコメントをもとに

<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> 

UPDATE

しかし、私はまだエラーを受けており、エンティティ間のフローと接続を理解していない可能性がありますが、元の質問には回答があります。

@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を追加するまで、また@ jmstemplateとconnectionfactoryを@Autowiringするまで、何も実行できませんでした。

実行している場合は、私が今受けてるエラーは次のとおりです。

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: {} 

答えて

1

この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で、この段落に注意してください。

+0

ありがとうArtem。メッセージの順序はどのように変換されますか?おそらく私はそれを逃した。 – rcurrie

+0

M-m-m。私があなたの要求に正しく従うなら、 'JmsSendingMessageHandler'に' setOrder() 'を使うことができます。 –

+0

もう一度ありがとうございます。 Garyのソリューションでは、order = "1"のjms outbound-channel-adapterとorder = "2"のファイルを削除するservice-activatorがあります。 – rcurrie

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; 
} 
+0

私の答えを見てください。あなたの解決策が動作しても、そのようなモンスターで簡単なファイル削除操作をオーバーヘッドする必要はありません:-)。 –

+0

シンプルなソリューションを提供していただきありがとうございます。学習プロセスを楽しむだけで、モンスターは時々現れます:) –

関連する問題