什么是JMS?
引用百度百科上的說明:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId> <artifactId>gs-messaging-jms</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-broker</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
二、編寫消息接收器
package hello; public class Email { private String to; private String body; public Email() { } public Email(String to, String body) { this.to = to; this.body = body; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } @Override public String toString() { return String.format("Email{to=%s, body=%s}", getTo(), getBody()); } }
三、定義消息接收者
package hello; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; @Component public class Receiver { @JmsListener(destination = "mailbox", containerFactory = "myFactory") public void receiveMessage(Email email) { System.out.println("Received <" + email + ">"); } }
Receiver
也被稱為消息驅動的POJO。正如您在上面的代碼中所看到的,不需要實現任何特定的接口或方法具有任何特定的名稱。此外,該方法可以具有非常靈活的簽名。請特別注意,此類在JMS API上沒有導入。
四、使用Spring發送和接收JMS消息
package hello; import javax.jms.ConnectionFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.jms.annotation.EnableJms; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.support.converter.MappingJackson2MessageConverter; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessageType; @SpringBootApplication @EnableJms public class Application { @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. return factory; } @Bean // Serialize message content to json using TextMessage public MessageConverter jacksonJmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_type"); return converter; } public static void main(String[] args) { // Launch the application ConfigurableApplicationContext context = SpringApplication.run(Application.class, args); JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class); // Send a message with a POJO - the template reuse the message converter System.out.println("Sending an email message."); jmsTemplate.convertAndSend("mailbox", new Email("info@example.com", "Hello")); } }
@Bean注解,主要作用是控制反轉(IOC),同
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
</bean>
舉例說明:
例如以Message為例:
@Bean public String message() { return new String("hello"); }
它等價於
<bean id="message" class="java.lang.String">
<constructor-arg index="0" value="hello"/>
</bean>
通常情況下,有三種配置Bean的方式:
如圖所示
關於Bean注解三種配置法,深入介紹可以參考該博文:https://blog.csdn.net/icarus_wang/article/details/51649635
@EnableJms
觸發發現帶注釋的方法@JmsListener
,在封面下創建消息監聽器容器。
為清楚起見,我們還定義了一個在接收器注釋中myFactory
引用的bean JmsListener
。因為我們使用DefaultJmsListenerContainerFactoryConfigurer
Spring Boot提供的基礎結構,所以JmsMessageListenerContainer
它與默認情況下引導創建的基礎結構相同。
默認MessageConverter
是能夠轉換只有基本類型(例如String
,Map
,Serializable
)我們Email
是不是Serializable
故意的。我們想要使用Jackson並以文本格式將內容序列化為json(即作為a TextMessage
)。Spring Boot將檢測a的存在,MessageConverter
並將其與默認值JmsTemplate
和任何JmsListenerContainerFactory
創建者相關聯DefaultJmsListenerContainerFactoryConfigurer
。
JmsTemplate
使消息發送到JMS目的地變得非常簡單。在main
runner方法中,啟動后,您可以使用jmsTemplate
發送Email
POJO。因為我們的自定義MessageConverter
已自動關聯到它,所以只會生成一個json文檔TextMessage
。
你沒看到的兩個bean是JmsTemplate
和ConnectionFactory
。這些是由Spring Boot自動創建的。在這種情況下,ActiveMQ代理運行嵌入式。
注意:
Spring JmsTemplate
可以通過它的receive
方法直接接收消息,但這只能同步工作,這意味着它會阻塞。這就是為什么我們建議您使用偵聽器容器,例如DefaultMessageListenerContainer
使用基於緩存的連接工廠,這樣您就可以異步使用消息並以最大的連接效率。
最后運行結果如下圖所示: