簡體   English   中英

Spring Boot JMS主題不起作用

[英]Spring Boot JMS Topic not working

Spring Boot JMS Topic無法正常工作,其行為類似於隊列。

樣例代碼

應用

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

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

JMSConfig

@Configuration
@EnableJms
public class JMSConfig {

private static final String JMS_BROKER_URL = "vm://embedded?broker.persistent=false,useShutdownHook=false";
public static final String JMS_TOPIC_MAIL = "mailbox.topic";

@Bean
// Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("_type");
    return converter;
}

@Bean
public ActiveMQConnectionFactory amqConnectionFactory() {

    return new ActiveMQConnectionFactory(JMS_BROKER_URL);

}

@Bean
public CachingConnectionFactory connectionFactory() {

    return new CachingConnectionFactory(amqConnectionFactory());

}

@Bean
public ActiveMQTopic destinationTopic() {

    return new ActiveMQTopic(JMS_TOPIC_MAIL);
}

@Bean
public JmsTemplate jmsTemplate() {

    JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory());
    // jmsTemplate.setDefaultDestination(destinationTopic());;
    jmsTemplate.setDefaultDestinationName(JMS_TOPIC_MAIL);
    jmsTemplate.setConnectionFactory(connectionFactory());
    jmsTemplate.setMessageConverter(jacksonJmsMessageConverter());
    return jmsTemplate;
}

@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(
        ConnectionFactory connectionFactory,
        DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setPubSubDomain(true);
    factory.setConnectionFactory(connectionFactory());
    // 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.
    return factory;
}
}

聽眾在這里

第一聽眾

@Component
public class JMSTopicListener1 {

@JmsListener(destination = JMSConfig.JMS_TOPIC_MAIL, containerFactory = "jmsListenerContainerFactory")
public void receiveTopicMessage(Email email) {
    System.out.println("JMSTopicListener#1 Received <" + email + ">");
}
}

第二聽眾

@Component
public class JMSTopicListener2 {

@JmsListener(destination = JMSConfig.JMS_TOPIC_MAIL, containerFactory = "jmsListenerContainerFactory")
public void receiveTopicMessage(Email email) {
    System.out.println("JMSTopicListener#2 Received <" + email + ">");
}
}

通過網絡訪問

@RestController
public class WebController {

@Autowired
JmsTemplate jmsTemplate;


@RequestMapping("/sendEmail")
public String sendEmail() {

    System.out.println("Sending ************************ .");

    jmsTemplate.convertAndSend(JMSConfig.JMS_TOPIC_MAIL, new Email(
            "info@example.com", "Hello"));


    return "Email send success!!!";
}
}

烏普特是

發送************************。 收到JMSTopicListener#2

但是消息應該由兩個偵聽器訂閱,因為它與主題相關

添加到您的aplication.properties

spring.jms.pub-sub-domain=true

或將Bean Definiton代碼更改為:

@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(
        ConnectionFactory connectionFactory,
        DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    // 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.
    // As you said if you want to override Boot's defaults or 
    // values from aplication.properties you have to do it after configurer.configure()
    factory.setPubSubDomain(true);
    return factory;
}

更新

您也需要更新jmsTemplate才能使用主題

@Bean
public JmsTemplate jmsTemplate() {

    JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory());
    // jmsTemplate.setDefaultDestination(destinationTopic());;
    jmsTemplate.setDefaultDestinationName(JMS_TOPIC_MAIL);
    jmsTemplate.setConnectionFactory(connectionFactory());
    jmsTemplate.setMessageConverter(jacksonJmsMessageConverter());
    jmsTemplate.setPubSubDomain(true);
    return jmsTemplate;
}

要么

@RestController
public class WebController {

@Autowired
JmsTemplate jmsTemplate;

@Autowired
ActiveMQTopic  destinationTopic;

@RequestMapping("/sendEmail")
public String sendEmail() {

    System.out.println("Sending ************************ .");

    jmsTemplate.convertAndSend(destinationTopic, new Email(
            "info@example.com", "Hello"));


    return "Email send success!!!";
}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM