2015-05-17 4 views
8

Ich versuche Beispiel zu erstellen für Publish-Subscribe basierend auf @JmsListener Anmerkung: https://github.com/lkrnac/book-eiws-code-samples/tree/master/05-jms/0515-publish-subscribe@JmsListener Nutzung für Publish-Subscribe-Thema

Relevante Code-Schnipsel:

@Slf4j 
@SpringBootApplication 
@EnableScheduling 
public class JmsPublishSubscribeApplication { 

    public static void main(String[] args) throws InterruptedException { 
     SpringApplication.run(JmsPublishSubscribeApplication.class, args); 
    } 

    @Bean 
    public ActiveMQTopic simpleTopic() { 
     return new ActiveMQTopic("simpleTopic"); 
    } 

} 

@Component 
public class SimpleMessageListener1 { 

    @JmsListener(destination = "simpleTopic") 
    public void readMessage(String message) { 
     //.... 
    } 

} 

@Component 
public class SimpleMessageListener2 { 

    @JmsListener(destination = "simpleTopic") 
    public void readMessage(String message) { 
     //.... 
    } 

} 

Das Problem ist, dass das ist erhalten Verhalten:

2015-05-17 20:07:04.985 INFO 22983 --- [pool-1-thread-1] n.l.b.e.chapter05.SimpleMessageSender : Sending message: simple message 
2015-05-17 20:07:05.070 INFO 22983 --- [enerContainer-1] n.l.b.e.c.JmsPublishSubscribeApplication : Message Received: simple message via listener 2 
2015-05-17 20:07:05.975 INFO 22983 --- [pool-1-thread-1] n.l.b.e.chapter05.SimpleMessageSender : Sending message: simple message 
2015-05-17 20:07:05.986 INFO 22983 --- [enerContainer-1] n.l.b.e.c.JmsPublishSubscribeApplication : Message Received: simple message via listener 1 
2015-05-17 20:07:06.975 INFO 22983 --- [pool-1-thread-1] n.l.b.e.chapter05.SimpleMessageSender : Sending message: simple message 
2015-05-17 20:07:06.987 INFO 22983 --- [enerContainer-1] n.l.b.e.c.JmsPublishSubscribeApplication : Message Received: simple message via listener 2 
2015-05-17 20:07:07.975 INFO 22983 --- [pool-1-thread-1] n.l.b.e.chapter05.SimpleMessageSender : Sending message: simple message 
2015-05-17 20:07:07.994 INFO 22983 --- [enerContainer-1] n.l.b.e.c.JmsPublishSubscribeApplication : Message Received: simple message via listener 1 

Aber jede Nachricht sollte von beiden Listenern nach Definition der Themen verbraucht werden. Was vermisse ich?

+2

schreiben 'application.properties' und stellen Sie' spring.jms:

@Bean public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); // This provides all boot's default to this factory, including the message converter configurer.configure(factory, connectionFactory); // You could still override some of Boot's default if necessary. factory.setPubSubDomain(true); return factory; } 

Dies kann dann in der @JmsListener kommentierten Methode verwendet werden .pub-sub-domain' zu 'true'. –

+0

Kann bestätigen, dass dieses Flag funktioniert. Seltsam, dass es nicht funktioniert, wenn Sie es programmatisch machen: jmsTemplate.setPubSubDomain (true); – luboskrnac

+0

@ M.Deinum Wollen Sie keine Antwort erstellen, um Punkte zu sammeln? – luboskrnac

Antwort

21

Wenn ein @JmsListener Verwendung Sie verwendet eine DefaultMessageListenerContainer die die pubSubDomain Satz false hat JmsDestinationAccessor die standardmäßig erstreckt. Wenn diese Eigenschaft falsch ist, wird sie in einer Warteschlange ausgeführt. Wenn Sie Themen verwenden möchten, müssen Sie diesen Eigenschaftswert auf true setzen.

Wie Sie Spring Boot verwenden Sie ganz einfach diese Eigenschaft auf true, indem Sie die spring.jms.pub-sub-domain Eigenschaft auf den application.properties und setzen Sie ihn auf true einstellen.

spring.jms.pub-sub-domain=true 

Wenn ein @JmsListener mit ihm für eine jmsListenerContainerFactory namens Bean suchen, wenn das nicht verfügbar eine Standard erwartet wird. Sie können auch eine eigene Bean einfügen und diese Eigenschaft programmatisch unter true festlegen.

@Bean 
public DefaultMessageListenerContainer jmsListenerContainerFactory() { 
    DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer(); 
    dmlc.setPubSubDomain(true); 
    // Other configuration here 
    return dmlc; 
} 

Dies würde natürlich arbeiten auch, aber würde auf diese mehr Arbeit, mehr Informationen wird in der Dokumentation der @EnableJms annotation finden.

+0

Entführen Sie keine anderen nicht/vage verwandten Fragen, sondern stellen Sie stattdessen eine neue Frage. –

+0

Danke für Ihre Hilfe. Bitte, korrigieren Sie den Klassennamen: Sie haben "Dfeault" anstelle von "Default" geschrieben –

+0

Sie haben einen Tippfehler in DefeaultMessageListenerContainer und ich kann ihn nicht bearbeiten ... – kabeen

4

Der Standardzieltyp von @JmsListener von Queue zu Topic kann vollständig in Java geändert werden, ohne die Eigenschaften zu ändern oder XML zu verwenden.

Die Spring guide enthält ein Beispiel für das Anpassen der Standardeinstellungen, die von DefaultMessageListenerContainer bereitgestellt werden.

Es erfordert eine individuelle Bean definieren wie folgt:

@JmsListener(destination = "mailbox", containerFactory = "myFactory") 
public void receiveMessage(Email email) { 
    // implementation 
}