2015-05-17 8 views
8

Sto cercando di creare ad esempio per la pubblicazione-iscrizione sulla base di @JmsListener annotazione: https://github.com/lkrnac/book-eiws-code-samples/tree/master/05-jms/0515-publish-subscribeutilizzo @JmsListener per publish-subscribe argomento

frammenti di codice rilevanti:

@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) { 
     //.... 
    } 

} 

Il problema è che è ottenere questo comportamento:

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 

Ma ogni messaggio deve essere consumato da entrambi gli ascoltatori per definizione di argomenti. Cosa mi manca?

+2

Aggiungi un 'application.properties' e impostare' spring.jms .pub-sub-domain' a 'true'. –

+0

Posso confermare che questo flag funziona. Strano che non funzioni quando lo si fa in modo programmatico: jmsTemplate.setPubSubDomain (true); – luboskrnac

+0

@ M.Deinum Non vuoi creare una risposta per guadagnare punti? – luboskrnac

risposta

21

Quando si utilizza un @JmsListener utilizza un DefaultMessageListenerContainer estendentesi JmsDestinationAccessor che di default ha la pubSubDomain impostato a false. Quando questa proprietà è falsa, funziona su una coda. Se si desidera utilizzare argomenti, è necessario impostare questo valore di proprietà su true.

Come si utilizza Spring Boot si può facilmente impostare questa proprietà su true aggiungendo la proprietà spring.jms.pub-sub-domain al application.properties e impostarlo true.

spring.jms.pub-sub-domain=true 

Quando si utilizza un @JmsListener si è alla ricerca di un jmsListenerContainerFactory fagiolo di nome, se questo non è disponibile uno di default è previsto. Puoi anche includere il tuo bean e impostare questa proprietà a livello di programmazione true.

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

Ciò naturalmente anche funzionato, ma sarebbe più lavoro, più informazioni su questo si possono trovare nella documentazione del @EnableJms annotation.

+0

Non dirottare altre domande non/vagamente correlate, ponete invece una nuova domanda. –

+0

Grazie per il vostro aiuto. Per favore, correggi il nome della classe: hai scritto "Dfeault" invece di "Default" –

+0

Hai un errore di battitura in DefeaultMessageListenerContainer e non riesco a modificarlo ... – kabeen

4

Il cambio del tipo di destinazione predefinito di un @JmsListener da Queue a Topic può essere eseguito completamente in Java senza modificare le proprietà o utilizzando XML.

Spring guide contiene un esempio per la personalizzazione delle impostazioni predefinite fornite da DefaultMessageListenerContainer.

Si richiede la definizione di un fagiolo personalizzato come segue:

@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; 
} 

Questo può quindi essere utilizzato nel metodo @JmsListener annotato:

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