淺談jms之(用activemq實現jms實例)

之前在前面的文章已經有對activemq的簡單介紹以及安裝部署,今天打算把空閒時寫的幾個關於以activemq 爲mom(中間件)實現jms的案例拿出來寫寫,今天的這個例子是不使用spring進行封裝的,

 jms提供的api中有兩種消息傳遞的方式,點到點(queue隊列)和pub\sub訂閱(topic主題)方式;在之前的文章已經仔細講過兩種方式的不同了。

 首先在寫demo之前,我們都需要創建一個maven工程,在pom中引入我們所需要和依賴的jar包,這裏用的是activemq-core5.7.0的版本jar

<span style="white-space:pre">		</span><dependency>
    		<span style="white-space:pre">	</span><groupId>org.apache.activemq</groupId>
    		<span style="white-space:pre">	</span><artifactId>activemq-core</artifactId>
    		<span style="white-space:pre">	</span><version>5.7.0</version>
		</dependency>
(1)對於點對點模式的開發流程:

 點對點(queue隊列)模式,必須要有一個Producer (生產者) 和一個Customer(消費者);

所以首先我們要先創建一個生產者類,

QueueProducer.java

/**
 * 點到點
 * @author leo
 *   Producer開發流程
 *   1.1 創建Connection: 根據url,user和password創建一個jms Connection。 
	 1.2 創建Session: 在connection的基礎上創建一個session,同時設置是否支持事務和ACKNOWLEDGE標識。 
     1.3 創建Destination對象: 需指定其對應的主題(subject)名稱,producer和consumer將根據subject來發送/接收對應的消息。 
     1.4 創建MessageProducer: 根據Destination創建MessageProducer對象,同時設置其持久模式。 
     1.5 發送消息到隊列(Queue): 封裝TextMessage消息,使用MessageProducer的send方法將消息發送出去。 
 * 
 *
 */
public class QueueProducer {
	//user
	private static String user =ActiveMQConnection.DEFAULT_USER;
	//password
	private static String password =ActiveMQConnection.DEFAULT_PASSWORD;
	//url
	private static String url ="tcp://localhost:61616";
	
	public static void main(String[] args) {
		//創建連接工廠
		ConnectionFactory connectionFactory =new ActiveMQConnectionFactory(user, password, url);
		try {
			//創建連接 connection :JMS 客戶端到JMS Provider 的連接  
			Connection connection =connectionFactory.createConnection();
			//開啓連接
			connection.start();
			System.out.println("啓動連接");
			//創建session 一個發送或接收消息的線程 
			Session session =connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
			//創建Queue : 需指定其對應的主題(subject)名稱,producer和consumer將根據subject來發送/接收對應的消息。 
			Queue destination =session.createQueue("activemq-queue-test1");
			// MessageProducer:消息發送者 
			MessageProducer producer = session.createProducer(destination);
			//在此處不做持久化
			producer.setDeliveryMode(DeliveryMode.PERSISTENT); 
			//
			sendMsg(session,producer);
			//
			session.commit();
			//關閉連接
			connection.close();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 發送消息
	 * @param session
	 * @param producer
	 * @throws JMSException
	 */
	private static void sendMsg(Session session, MessageProducer producer) throws JMSException {
		
			TextMessage message =session.createTextMessage("activemq 點到點消息:");
			System.out.println(message.getText());
			producer.send(message);
		
	}
}
然後再創建一個消費者類:

QueueCustomer.java

/**
 * @author leo
 * Customer
 *2.1 實現MessageListener接口: 消費者類必須實現MessageListener接口,然後在onMessage()方法中監聽消息的到達並處理。 
  2.2 創建Connection: 根據url,user和password創建一個jms Connection,如果是durable模式,還需要給connection設置一個clientId。 
  2.3 創建Session和Destination: 與ProducerTool.java中的流程類似,不再贅述。 
  2.4 創建replyProducer【可選】:可以用來將消息處理結果發送給producer。 
  2.5 創建MessageConsumer:  根據Destination創建MessageConsumer對象。 
  2.6 消費message:  在onMessage()方法中接收producer發送過來的消息進行處理,並可以通過replyProducer反饋信息給producer 
 *
 */
public class QueueCustomer {
	//user
		private static String user =ActiveMQConnection.DEFAULT_USER;
		//password
		private static String password =ActiveMQConnection.DEFAULT_PASSWORD;
		//url
		private static String url ="tcp://localhost:61616";
		
		public static void main(String[] args) {
			//創建連接工廠
			ConnectionFactory connectionFactory =new ActiveMQConnectionFactory(user, password, url);
			try {
				//創建連接 connection :JMS 客戶端到JMS Provider 的連接  
				Connection connection =connectionFactory.createConnection();
				//開啓連接
				connection.start();
				System.out.println("啓動連接");
				//創建session 一個發送或接收消息的線程 
				final Session session =connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
				//創建Queue : 需指定其對應的主題(subject)名稱,producer和consumer將根據subject來發送/接收對應的消息。 
				Queue destination =session.createQueue("activemq-queue-test1");
				//創建MessageConsumer:  根據Destination創建MessageConsumer對象。  用來接收消息
				MessageConsumer consumer = session.createConsumer(destination);
				//消費者實現監聽接口,消費信息
				consumer.setMessageListener(new MessageListener() {
					
					@Override
					public void onMessage(Message arg0) {
						try {  
		                    TextMessage textMessage=(TextMessage)arg0;  
		                    System.out.println(textMessage.getText());  
		                } catch (JMSException e1) {  
		                    e1.printStackTrace();  
		                }  
		                try {  
		                    session.commit();  
		                } catch (JMSException e) {  
		                    e.printStackTrace();  
		                }  
						
					}
				});
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}


}
然後我們編譯生產者類看看是否信息被髮送到mq Queue隊列中;但是需要注意的是:編譯之前要先啓動activeMQ 服務,並且登錄http://localhost:8161/admin/queues.jsp,進行驗證一下。


發現新的隊列已經創建,並且有一條消息在隊列中。然後我們編譯消費者,看消息是否能被消費者消費


發現消息被取走,然後看queues 中的隊列已經沒有消息了。這樣一個簡單的queue模式的jms已經完成。

(2)對於topic模式,之前在前面也說過該模式的開發流程,一個topic要有一個發佈者(publisher),但是可以有多個訂閱者(Subscriber);那首先我們來創建一個

publisher類:

 /* 
 * 
 * 
 * @author leo 
 * Publisher(發佈者)
 * 2.1 實現MessageListener接口:在onMessage()方法中接收訂閱者的反饋消息。 
   2.2 創建Connection: 根據url,user和password創建一個jms Connection。 
   2.3 創建Session: 在connection的基礎上創建一個session,同時設置是否支持事務和ACKNOWLEDGE標識。 
   2.4 創建Topic: 創建2個Topic,topictest.messages用於向訂閱者發佈消息,topictest.control用於接 收訂閱者反饋的消息。這2個topic與訂閱者開發流程中的topic是一一對應的。 
   2.5 創建consumer和producer對象: 根據topictest.messages創建publisher; 根據topictest.control 創建consumer,同時監聽訂閱者反饋的消息。
   2.6 給所有訂閱者發送消息,並接收反饋消息:  示例代碼中,一共重複10輪操作。 每輪先向所有訂閱者 發送2000個消息; 然後堵塞線程,開始等待; 最後通過onMessage()方法,接收到訂閱者反饋的“REPORT”類信息後,才print反饋信息並解除線程堵塞,進入下一輪。
 *
 */
public class TopicPublisher {
	//user
		private static String user =ActiveMQConnection.DEFAULT_USER;
		//password
		private static String password =ActiveMQConnection.DEFAULT_PASSWORD;
		//url
		private static String url ="tcp://localhost:61616";
		
		public static void main(String[] args) {
			//創建連接工廠
			ConnectionFactory connectionFactory =new ActiveMQConnectionFactory(user, password, url);
			try {
				//創建連接 connection :JMS 客戶端到JMS Provider 的連接  
				Connection connection =connectionFactory.createConnection();
				//開啓連接
				connection.start();
				System.out.println("啓動連接");
				//創建session 一個發送或接收消息的線程 
				Session session =connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
				//創建tipic : 需指定其對應的主題(subject)名稱,producer和consumer將根據subject來發送/接收對應的消息。 
				Topic destination =session.createTopic("activemq-topic-test");
				// MessageProducer:消息發送者 
				MessageProducer producer = session.createProducer(destination);
				//在此處不做持久化
				producer.setDeliveryMode(DeliveryMode.PERSISTENT); 
				//
				sendMsg(session,producer);
				//
				session.commit();
				//關閉連接
				connection.close();
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}

		private static void sendMsg(Session session, MessageProducer producer) throws JMSException {
			for (int i = 0; i < 50; i++) {
				TextMessage message =session.createTextMessage("activemq topic(pub/sub)的 消息:"+i);
				System.out.println(message.getText());
				producer.send(message);
			}
		}
}
還有創建一個訂閱該消息的訂閱者topicSubscriber:

/**
 * 
 * @author leo
 *Subscriber (訂閱者開發流程)
 *1.1 實現MessageListener接口: 在onMessage()方法中監聽發佈者發出的消息隊列,並做相應處理。 
  1.2 創建Connection: 根據url,user和password創建一個jms Connection。 
  1.3 創建Session: 在connection的基礎上創建一個session,同時設置是否支持事務和ACKNOWLEDGE標識。 
  1.4 創建Topic:  創建2個Topic, topictest.messages用於接收發布者發出的消息,topictest.control 用於向發佈者發送消息,實現雙方的交互。 
  1.5 創建consumer和producer對象:根據topictest.messages創建consumer,根據topictest.control創建 producer。 
  1.6 接收處理消息:在onMessage()方法中,對收到的消息進行處理,可直接簡單在本地顯示消息,或者根 據消息內容不同處理對應的業務邏輯(比如:數據庫更新、文件操作等等),並且可以使用producer對象將處理結果返回給發佈者。 
 */
public class TopicSubscriber {
	//user
	private static String user =ActiveMQConnection.DEFAULT_USER;
	//password
	private static String password =ActiveMQConnection.DEFAULT_PASSWORD;
	//url
	private static String url ="tcp://localhost:61616";
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ConnectionFactory connectionFactory =new ActiveMQConnectionFactory(user, password, url);
		try {
			//創建連接 connection :JMS 客戶端到JMS Provider 的連接  
			Connection connection =connectionFactory.createConnection();
			//開啓連接
			connection.start();
			System.out.println("啓動連接");
			//創建session 一個發送或接收消息的線程 
			final Session session =connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
			//創建Queue : 需指定其對應的主題(subject)名稱,producer和consumer將根據subject來發送/接收對應的消息。 
			Topic destination =session.createTopic("activemq-topic-test");
			//創建MessageConsumer:  根據Destination創建MessageConsumer對象。  用來接收消息
			MessageConsumer consumer = session.createConsumer(destination);
			//實現監聽接口,消費信息
			consumer.setMessageListener(new MessageListener() {
				
				@Override
				public void onMessage(Message arg0) {
					try {
						TextMessage message =(TextMessage) arg0;
						System.out.println(message.getText());
						session.commit();
					} catch (JMSException e) {
						e.printStackTrace();
					}
				}
			});
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}

}
和queue一樣,我們先啓動發佈者,會發現在mq管理員界面中的topic板塊中會有一個新的主題以及消息,然後再啓動訂閱者,會發現訂閱者沒有收到之前發佈者發佈的那些消息。所以Queue(點對點)方式和Topic(發佈/訂閱)方式 的運行結果有了區別是:在Queue(點對點)方式中先運行生產者,再運行消費者,消費者還能接受到消息;

而Topic(發佈/訂閱)方式就不同了,先運行發佈者,再運行訂閱者,訂閱者收到的消息可能沒有或者是不完全的。所以我們要先運行訂閱者,然後再去編譯發佈者。








發佈了25 篇原創文章 · 獲贊 20 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章