2

ejb 3.1、サーブレット3.0(glassfishサーバーv3)を使用

シナリオ:jmsメッセージをリッスンし、他のセッションBean(ステートレス)に処理を提供するMDBがあります。jmsリソースを注入するServelet。

質問1:静的宣言を使用するときにサーブレットがjmsリソースを挿入できないのはなぜですか?

@Resource(mappedName = "jms/Tarturus")
private static ConnectionFactory connectionFactory;

@Resource(mappedName = "jms/StyxMDB")
private static Queue queue;


private Connection connection;

@PostConstruct
    public void postConstruct() {
        try {
            connection = connectionFactory.createConnection();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

    @PreDestroy
    public void preDestroy() {
        try {
            connection.close();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

私が得るエラーは次のとおりです:

[#| 2010-05-03T15:18:17.118 +0300|警告|glassfish3.0| javax.enterprise.system.container.web.com.sun.enterprise.web | _ThreadID = 35; _ThreadName = Thread-1; | StandardWrapperValve [WorkerServlet]:PWC1382:サーブレットWorkerServletの例外を割り当てますcom.sun.enterprise.container.common.spi.util.InjectionException:com.sunでクラスua.co.rufous.server.services.WorkerServiceImplの管理対象オブジェクトを作成中にエラーが発生しました。 company.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:312)at com.sun.enterprise.web.WebContainer.createServletInstance(WebContainer.java:709)atcom.sun.enterprise.web.WebModule。 createServletInstance(WebModule.java:1937)at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1252)原因:com.sun.enterprise.container.common.spi.util。InjectionException:未解決のMessage-Destination-Refua.co.rufous.server.services.WorkerServiceImpl/queue@java.lang.String@nullをcom.sunのクラスua.co.rufous.server.services.WorkerServiceImplに挿入しようとしたときに例外が発生しました.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:614)at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:384)at com.sun .enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:141)at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:127)at com.sun .enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:306)... 27その他原因:com.sun.enterprise.container.common.spi.util.InjectionException:インスタンスベースのインジェクションのみをサポートするクラスでの静的フィールドprivate staticjavax.jms.Queueua.co.rufous.server.services.WorkerServiceImpl.queueの不正使用com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:532)で... 31詳細|#]

私のMDB:

/**
 * asadmin commands
 * asadmin create-jms-resource --restype javax.jms.ConnectionFactory jms/Tarturus
 * asadmin create-jms-resource --restype javax.jms.Queue jms/StyxMDB
 * asadmin list-jms-resources
 */
@MessageDriven(mappedName = "jms/StyxMDB", activationConfig =
{
    @ActivationConfigProperty(propertyName = "connectionFactoryJndiName", propertyValue = "jms/Tarturus"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})

public class StyxMDB implements MessageListener {

    @EJB
    private ActivationProcessingLocal aProcessing;

    public StyxMDB() {
   }

    public void onMessage(Message message) {
        try {
            TextMessage msg = (TextMessage) message;
            String hash = msg.getText();
            GluttonyLogger.getInstance().writeInfoLog("geted jms message hash = " + hash);
        } catch (JMSException e) {

        }

    }


}

静的宣言がなくてもすべてが正常に機能します。

@Resource(mappedName = "jms/Tarturus")
    private ConnectionFactory connectionFactory;

    @Resource(mappedName = "jms/StyxMDB")
    private Queue queue;

    private Connection connection;

質問2:MDBを操作するためのベストプラクティスは何ですか:onMessage()で完全なリクエストを処理するか、onMessage()メソッドで別のBean(私の場合はステートレスBean)を呼び出して処理します。ソープサービスへの呼び出しをほとんど含まない処理なので、完全な処理時間は3秒になる可能性があります。

ありがとうございました。

4

1 に答える 1

6

回答:
1. 静的フィールドにリソースを注入することはできません。メンバー フィールドへの注入はオブジェクトの構築中に発生し、静的フィールドはオブジェクトの一部ではありません (クラスの一部のみ)。さらに、EJB とサーブレットはスレッド化されたオブジェクトであるため、これを行うのは危険な場合があります。
2. 処理を複数の EJB に分割することが理にかなっている場合は、そのようにします。それ以外の場合は、onMessage() での処理が完全に有効です。

私ができる追加の提案の 1 つは、EE 6 仕様に新たに追加され、豊富な依存性注入を提供するCDIを検討することです。

非同期操作を実行するために MDB を使用していますか? サーブレット 3.0 にはいくつかの優れた非同期機能があります。Servlet 3.0 に慣れていない場合は、プレゼンテーション全体を見ることをお勧めします。

于 2010-05-03T12:53:07.480 に答える