| Oracle® Fusion Middleware Oracle WebLogic ServerメッセージドリブンBeanのプログラミング 11g リリース1 (10.3.6) B61425-04 |
|
![]() 前 |
![]() 次 |
次のトピックでは、EJB 3.0準拠MDBのプログラミングと実装の方法について説明します。
EJB 3.0準拠MDBを実装するには、『Oracle WebLogic Server Enterprise JavaBeansバージョン3.0のプログラミング』の「EJB 3.0開発プロセスの概要」に説明されている手順を実行します。
EJB 3.0準拠MDBをプログラミングするには、『Oracle WebLogic Server Enterprise JavaBeansバージョン3.0のプログラミング』の「Beanファイルのプログラミング: 通常の手順」で説明されている手順を実行します。
EJBタイプをメッセージドリブンとして宣言するには、@javax.ejb.MessageDrivenアノテーションを使用する必要があります。次のオプション属性を指定できます。
messageListenerInterface - メッセージ・リスナー・インタフェースを明示的に実装していない場合や、Beanに追加のインタフェースを実装する場合に、メッセージ・リスナー・インタフェースを指定します。
|
注意: Beanでサポートするメッセージング・タイプに必要なメッセージ・リスナー・インタフェース(またはそのメッセージ・リスナー・インタフェースのメソッド)を、Beanクラスに直接的または間接的に実装する必要があります。JMSの場合であれば、メッセージ・リスナー・インタフェースはjavax.jms.MessageListenerインタフェースになります。 |
activationConfig: 動作環境でBeanを構成する配列構成プロパティを指定します。
アクティブ化構成プロパティは、MDBのデプロイ時にMDBコンテナに渡される名前と値のペアです。このプロパティは、ejb-jar.xmlデプロイメント記述子内または、MDB Beanクラスで@ActivationConfigPropertyアノテーションを使用するかのいずれかの方法で宣言できます。@ActivationConfigPropertyアノテーションを使用する例は、例7-1に示されています。ejb-jar.xmlデプロイメント記述子を使用する例は、例7-2に示されています。
例7-1 @ActivationConfigPropertyコード例
. . .
@ActivationConfigProperties(
{
@ActivationConfigProperty(
name="connectionFactoryJndiName", value="JNDINameOfMDBSourceCF"
),
@ActivationConfigProperty(
name="initialContextFactory", value="weblogic.jndi.WLInitialContextFactory"
)
}
)
. . .
ejb-jar.xml記述子でアクティブ化構成プロパティを設定するには、例7-2で示されているように、message-drivenスタンザのactivation-config-property要素を使用します。
例7-2 ejb-jar.xmlで設定されるアクティブ化構成プロパティ
<message-driven>
. . .
<activation-config>
<activation-config-property>
<activation-config-property-name>destinationJNDIName</activation-config-property-name>
<activation-config-property-value>myQueue</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
<activation-config-property>
</activation-config>
. . .
</message-driven>
<message-driven>
. . .
<activation-config>
<activation-config-property>
<activation-config-property-name>destinationJNDIName</activation-config-property-name>
<activation-config-property-value>myQueue</activation-config-property-value>
</activation-config-property>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Queue</activation-config-property-value>
<activation-config-property>
</activation-config>
. . .
</message-driven>
アクティブ化構成プロパティは、ejb.jarデプロイメント記述子内か、またはactivationConfigPropertyアノテーション・プロパティを使用することで設定できるため、両方の場所で同じ名前が使用される場合には競合が起こる場合があります。3.0以前のバージョンのEJBまたは独自のWebLogic Server EJBアノテーションから同一の名前のプロパティを使用することによっても、競合が起こる可能性があります。このような競合は、高から低の順番で次の優先順序に従うと解決されます。
weblogic-ejb-jar.xmlデプロイメント記述子に設定されるプロパティ
固有のWebLogic Server 10.0 (以降)のアノテーション
ejb-jar.xmlデプロイメント記述子に設定されるactivation-config-propertyプロパティ
activationConfigPropertyアノテーション・プロパティ
たとえば、同一のプロパティがweblogic-ejb-jar.xml記述子およびejb-jar.xml記述子に存在する場合、weblogic-ejb-jar.xmlの方のプロパティが優先順位が高くなり、ejb-jar.xmlの値をオーバーライドします。あるいは、同一のプロパティがejb-jar.xml記述子の要素およびactivationConfigPropertyアノテーションの両方に設定されている場合、記述子の要素の方が優先され、アノテーションは無視されます。
アクティブ化構成プロパティの詳細は、『Oracle WebLogic Server Enterprise JavaBeansバージョン3.0のプログラミング』のjavax.ejb.ActivationConfigPropertyに関する項を参照してください。表11-1では、WebLogic Serverによってサポートされるアクティブ化構成プロパティをまとめてあるので、こちらも参照してください。
「MDBとメッセージング・モデル」で説明されているメッセージング・モードをサポートするMDBの開発の詳細は、「MDBのプログラミングと構成: 詳細」を参照してください。
例7-3はWebLogic MDBを示します。これは、(WebLogic Server 10.3.4以降の)WebLogic JMSキューへのサブスクリプションを使用し、メッセージ・トランザクションを処理してターゲットの宛先にメッセージを転送します。
JMS接続ファクトリMyCFを使用してMDBは接続し、キューMyQueueから受信します。そして、接続ファクトリMyTargetCFから生成された接続を使用して、メッセージをMyTargetDestに転送します。
リソース参照プーリング・ノート: MDBは、リソース参照を使用してMyTargetCFにアクセスします。リソース参照は、『Oracle WebLogic Server JMSのプログラミング』のWebLogic JMSをEJBおよびサーブレットと併用するための拡張サポートに関する項で説明されているように、自動的にJMSプロデューサ・プーリングを有効化します。
キューではなくトピックを使用する同様のサンプルは、例10-1「分散トピックを使用するMDBのサンプル」を参照してください。
例7-3 分散キューを使用するMDBのサンプル
package test;
import javax.annotation.Resources;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jms.*;
@MessageDriven(
name = "MyMDB",
activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "connectionFactoryJndiName",
propertyValue = "MyCF"), // External JNDI Name
@ActivationConfigProperty(propertyName = "destinationJndiName",
propertyValue = "MyQueue") // Ext. JNDI Name
}
)
@Resources ({
@Resource(name="targetCFRef",
mappedName="MyTargetCF", // External JNDI name
type=javax.jms.ConnectionFactory.class),
@Resource(name="targetDestRef",
mappedName="MyTargetDest", // External JNDI name
type=javax.jms.Destination.class)
})
public class MyMDB implements MessageListener {
// inject a reference to the MDB context
@Resource
private MessageDrivenContext mdctx;
// cache targetCF and targetDest for re-use (performance)
private ConnectionFactory targetCF;
private Destination targetDest;
@TransactionAttribute(value = TransactionAttributeType.REQUIRED)
public void onMessage(Message message) {
System.out.println("My MDB got message: " + message);
// Forward the message to "MyTargetDest" using "MyTargetCF"
Connection jmsConnection = null;
try {
if (targetCF == null)
targetCF = (javax.jms.ConnectionFactory)mdctx.lookup("targetCFRef");
if (targetDest == null)
targetDest = (javax.jms.Destination)mdctx.lookup("targetDestRef");
jmsConnection = targetCF.createConnection();
Session s = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer mp = s.createProducer(null);
mp.send(targetDest, message);
} catch (JMSException e) {
System.out.println("Forcing rollback due to exception " + e);
e.printStackTrace();
mdctx.setRollbackOnly();
} finally {
// Closing a connection automatically returns the connection and
// its session plus producer to the resource reference pool.
try { if (jmsConnection != null) jmsConnection.close(); }
catch (JMSException ignored) {};
}
// emulate 1 second of "think" time
try { Thread.currentThread().sleep(1000); }
catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // Restore the interrupted status
}
}
}