Oracle® Fusion Middleware Oracle WebLogic ServerメッセージドリブンBeanの開発 12c (12.1.2) E48048-01 |
|
前 |
次 |
この章では、EJB 3.1準拠MDBのプログラミングと実装の方法について説明します。
EJB 3.1準拠のMDBを実装するには、『Oracle WebLogic Server Enterprise JavaBeansの開発』のEJB開発プロセスの概要に関する項で説明している手順を実行します。
EJB 3.1準拠MDBをプログラミングするには、『Oracle WebLogic Server Enterprise JavaBeansの開発』のBeanファイルのプログラミング: 通常の手順に関する項で説明している手順を実行します。
EJBタイプをメッセージドリブンとして宣言するには、@javax.ejb.MessageDriven
アノテーションを使用する必要があります。次のオプション属性を指定できます。
messageListenerInterface
- メッセージ・リスナー・インタフェースを明示的に実装していない場合や、Beanに追加のインタフェースを実装する場合に、メッセージ・リスナー・インタフェースを指定します。
注意: Beanでサポートするメッセージング・タイプに必要なメッセージ・リスナー・インタフェース(またはそのメッセージ・リスナー・インタフェースのメソッド)を、Beanクラスに直接的または間接的に実装する必要があります。JMSの場合であれば、メッセージ・リスナー・インタフェースは |
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の開発』のjavax.ejb.ActivationConfigPropertyに関する項を参照してください。表11-1では、WebLogic Serverによってサポートされるアクティブ化構成プロパティをまとめてあるので、こちらも参照してください。
注意: Enterprise JavaBean仕様に基づき、 |
「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 } } }