理解MDB機制:
1、底層使用的是RPC協議,就像RMI,不過RMI是同步的消息,而RPC是異步的。
2、客戶端不會直接調用MDB,它是由發送到服務器的消息觸發的。典型的消息服務器有:IBM websphere MQ等。
3、MDB直接處理消息,消息涉及到在兩個不同的進程間通信,他們通常位於不同的機器上。Java EE通過在發送者和接受者之間添加中間件(Message Oriented Middleware,MOM)使得消息服務更加健壯--消息兩端不需要同時使用,系統組件中間進行松耦合。在java EE系統中,消息中間件成爲Destination。Java EE通過JMS API對消息服務進行標準化。
4、MDB和SLSB一樣,也使用了實例池技術,容器可以使用一定數量的bean實例處理成百上千的JMS消息。
5、注意:應用時,session context不能注入MDB,MD context也不能注入session bean。
6、MDB通常要實現MessageListener接口,該接口定義了onMessage()方法。MDB通過它來處理收到的JMS消息。
7、當容器檢測到bean守候的目標地址有消息到達時,容器調用onMessage方法將消息作爲參數傳入MDB。MDB在該方法中決定如何處理該消息。可以使用註解指定MDB監聽哪一個目標地址(destination).當MDB部署時,容器將讀取其中的配置信息。
JMS(Java Message Service):
1、jms支持兩種消息傳遞模型
(1)點對點模式(Point to Point,PTP):來自一個消息生產者(Producer)的消息只發送給一個消息的消費者(Customer)。PTP消息模式的destination又稱爲隊列(Queue)。如果消費者不在線的話,消息會駐留在MOM內,發送幾次就保存幾次,等到消費者上線後全部送出(例如QQ留言)。
(2)發佈-訂閱模式(Publish-Subscribe,pub-sub):類似於新聞組。一個消息生產者生產的消息可以有多個消費者消費。發佈訂閱模式的destination稱爲主題(Topic)。此種模式典型應用於跨系統的信息廣播。如果消費者不在線,生產者發送的消息不會送達該消費者,消費者上線後也不會收到。
2、jms中的消息
一條message一般由三部分組成:頭(head)、屬性(property)和主體(body)。
消息有幾種類型,均派生自Message接口:StreamMessage、MapMessage、TextMessage、ObjectMessage和ByteMessage。
3、在java類中發送消息的步驟的示例代碼:
發送端:
public class JMSApp { //如果是Topic,下面的QueueConnectionFactory換成TopicConnectionFactory
public static void main(String[] args) {
try {
//0. 得到一個JNDI初始化上下文
InitialContext ctx = new InitialContext();
//1. 獲得服務器上的隊列連接工廠,該連接工廠是由JMS提供的,不需要我們自己創建。
//每個供應商都爲它綁定了一個全局JNDI,例如下文引號裏的QueueConnectionFactory。
QueueConnectionFactory qcf = (QueueConnectionFactory)ctx.lookup("QueueConnectionFactory");
//2. 通過連接工廠創建隊列連接
QueueConnection qconn = qcf.createQueueConnection();
//3. 通過連接創建隊列的會話,參數含義爲(該會話需不需要事務,消息接收確認模式)
QueueSession qs = qconn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
//4. 獲得服務器上的隊列
Queue queue = (Queue)ctx.lookup("queue/testQueue");
//5. 通過回話,創建該列隊的消息的生產者
MessageProducer mp = qs.createProducer(queue);
//6. 通過回話創建文本消息
TextMessage txt = qs.createTextMessage();
txt.setText("你好嗎?");
mp.send(txt);
//7. 釋放資源
qs.close();
qconn.close();
System.out.println("消息發送完畢!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
接收端:
@MessageDriven(activationConfig={@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",propertyValue="queue/testQueue")})
public class MyQueueMDB implements MessageListener {
public void onMessage(Message arg0) {
try {
if(arg0 instanceof TextMessage){
TextMessage txt = (TextMessage)arg0;
System.out.println("MyQueueMDB 收到消息 : " + txt.getText());
System.out.println("我很好!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
下面是徐培成老師提供的課外知識:)
在一些數據量超大的應用中,例如移動、聯通、某些銀行業務等,有的可以說是直接用存儲過程開發程序。因爲當數據量大到一定程度的時候,應用程序本身就是瓶頸之一:因爲這些應用程序要從數據庫提取數據,就會佔用網絡流量;還要實例化對象放到內存裏,但有些數據並不需要挨個查看,這些都降低了總程序的效率--以前認識一開發的小孩,問他上班幹嘛,答曰:寫存儲過程,而且成百上千行地寫。。。。。。
關於ejb3其他更多的知識點,歡迎來傳智播客聆聽~~~