在servlet中注入jms资源& MDB的最佳实践

时间:2010-05-03 12:38:58

标签: servlets jms java-ee-6 ejb-3.1 message-driven-bean

使用ejb 3.1,servlet 3.0(glassfish server v3)

方案: 我有MDB,它监听jms消息并处理其他会话bean(无状态)。 Servelet注入jms资源。

问题1:为什么servlet在使用静态声明时不能注入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:为...分配例外   servlet WorkerServlet   com.sun.enterprise.container.common.spi.util.InjectionException:   创建托管对象时出错   类   ua.co.rufous.server.services.WorkerServiceImpl     在   com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:312)     在   com.sun.enterprise.web.WebContainer.createServletInstance(WebContainer.java:709)     在   com.sun.enterprise.web.WebModule.createServletInstance(WebModule.java:1937)     在   org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1252)   引起:   com.sun.enterprise.container.common.spi.util.InjectionException:   尝试注射的例外情况   未解决的消息目的地参考   ua.co.rufous.server.services.WorkerServiceImpl /队列@ java.lang.String中@空   进入课堂   ua.co.rufous.server.services.WorkerServiceImpl     在   com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:614)at   com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:384)     在   com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:141)     在   com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:127)     在   com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:306)     ... 27更多引起:   com.sun.enterprise.container.common.spi.util.InjectionException:   非法使用静态字段私有   static javax.jms.Queue   ua.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秒。

谢谢。

1 个答案:

答案 0 :(得分:6)

回答:
1.您无法将资源注入静态字段。在对象构造期间注入成员字段,静态字段不是对象的一部分(仅是类的一部分)。此外,EJB和servlet是线程对象,因此这可能是危险的 2.如果将处理拆分为多个EJB是有道理的,那么在onMessage()中处理是完全有效的。

我可以给出的另一个建议是,您应该查看CDI这是EE 6规范的新增内容,并提供丰富的依赖注入。

您使用MDB执行异步操作,Servlet 3.0有一些整洁的异步capabilities。如果您不熟悉Servlet 3.0,我建议您观看整个演示文稿。