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

Servlets 在servlet中注入jms资源&;MDB的最佳实践,servlets,jms,java-ee-6,ejb-3.1,message-driven-bean,Servlets,Jms,Java Ee 6,Ejb 3.1,Message Driven Bean,使用EJB3.1、Servlet3.0(glassfish服务器v3) 情景: 我有一个MDB,它侦听jms消息并将处理交给其他会话bean(无状态)。 Servelet注入jms资源 问题1:为什么servlet在使用静态声明时不能注入jms资源 @Resource(mappedName = "jms/Tarturus") private static ConnectionFactory connectionFactory; @Resource(mappedName = "jms/StyxM

使用EJB3.1、Servlet3.0(glassfish服务器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;

我得到的错误是:

[#2010-05-03T15:18:17.118+0300 | WARNING | glassfish3.0 | javax.enterprise.system.container.web.com.sun.enterprise.web | u ThreadID=35;_ThreadName=Thread-1;| StandardWrapperValve[WorkerServlet]: PWC1382:为分配异常 servlet WorkerServlet com.sun.enterprise.container.common.spi.util.InjectionException: 为创建托管对象时出错 班 ua.co.RUFUUS.server.services.WORKERSERSERVICEIMPL 在 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.RUFUUS.server.services.WORKERSERSERVICEIMPL/queue@java.lang.String@空的 上课 ua.co.RUFUUS.server.services.WORKERSERSERVICEIMPL 在 com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.\u inject(InjectionManagerImpl.java:614)位于 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: 非法使用静态字段私有 静态javax.jms.Queue ua.co.rufuus.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)来处理它。 处理包括对soap服务的少量调用,因此整个处理时间可能为3秒

谢谢。

答案:
1.不能将资源注入静态字段。成员字段的注入发生在对象构造期间,静态字段不是对象的一部分(只是类的一部分)。此外,EJB和servlet是线程对象,因此这样做可能会很危险。
2.如果将处理拆分为多个EJB是有意义的,那么就这样做,否则onMessage()中的处理是完全有效的

我可以给出的另一个建议是,您应该看看这是对EE6规范的一个新添加,它提供了丰富的依赖注入


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

我的Servlet实际上是GWT Servlet,因此我需要测试GWT是否与Servlet 3.0异步方法兼容。实际上,gwt有自己的gwt.runAsync()方法,还没有深入了解它是否自然地支持与servlet 3.0相同的异步方法,或者它是否通过servlet的3.0异步方法工作。好的,看起来我可以在没有MDB的情况下处理所有需要的东西。关于GWT.runAsync()-它是不同的。非常好的介绍,谢谢!
@Resource(mappedName = "jms/Tarturus")
    private ConnectionFactory connectionFactory;

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

    private Connection connection;