为什么Weld在Tomcat上说“不支持注入监听器”?

时间:2013-11-13 15:25:02

标签: java tomcat servlets resteasy weld

我有一个使用Resteasy的Web项目(反过来使用Weld)并部署到Tomcat 7.0.22(我在这里放了具体版本,以防这个版本特别适用于此版本)。

我有一个ServletContextListener,如下所示:

@WebListener
public class ApplicationInitialisationListener implements ServletContextListener {
    // create a logger here        

    @Inject
    HealthCheck healthCheck;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        if (healthCheck == null) {
            log.error("healthCheck is null");
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
}

部署到Tomcat后,记录了healthCheck is null,我也在日志中注意到这一行:

<2013-11-13 13:27:40,191> <pack> INFO pool-2-thread-1 org.jboss.weld.environment.tomcat7.Tomcat7Container - Tomcat 7 detected, CDI injection will be available in Servlets and Filters. Injection into Listeners is not supported

问题1 :为什么听众无法使用CDI注入?

我调查了这个answer,并说Load on startup via @Startup. There is currently no equivalent to this in CDI.

问题2 :问题1中描述的问题是这个问题的后果吗?

问题3 :我正在使用org.jboss.weld.servlet:weld-servlet:1.2.0.Beta1。在以后的版本中是否有关于启动支持的更新?

我看的相关问题 startup class in Weld

3 个答案:

答案 0 :(得分:1)

这是我发现的一种解决方法,可以在应用程序启动时注入CDI bean。

问题的要求可概括为:

  1. 在应用程序启动时注入CDI bean
  2. 使用bean做一些事情
  3. 解决方案大纲:

    1. 创建一个调用BeanManager.fireEvent(new SomeDummyEvent())
    2. 的WebListener
    3. 创建一个响应SomeDummyEvent并注入CDI bean的ApplicationScoped bean
    4. 示例代码:

      @WebListener
      public class ApplicationInitialisationListener implements ServletContextListener {
          private static final Logger LOG = Logger.getLogger(ApplicationInitialisationListener.class);
      
          @Override
          public void contextInitialized(ServletContextEvent event) {
              BeanManager beanManager = lookUpBeanManager();
              if (beanManager != null) {
                  beanManager.fireEvent(new SomeDummyEvent());
                  LOG.info("beanManager fired SomeDummyEvent.");
              } else {
                  LOG.error("beanManager is null.  Cannot fire startup event.");
              }
          }
      
          @Override
          public void contextDestroyed(ServletContextEvent servletContextEvent) {
          }
      
          public BeanManager lookUpBeanManager() {
              try {
                  // See reference below about how I came up with this
                  InitialContext iniCtx = new InitialContext();
                  BeanManager result = (BeanManager) iniCtx.lookup("java:comp/env/BeanManager");
                  return result;
              } catch (NamingException e) {
                  LOG.error("Could not construct BeanManager.", e);
                  return null;
              }
          }
      
          public static class SomeDummyEvent implements Serializable {
          }
      }
      

      @ApplicationScoped
      public class InitializationResourceBean {
      
          private static final Logger LOG = Logger.getLogger(InitializationResourceBean.class);
      
          @Inject
          HealthCheck healthCheck;
      
          public void listen(@Observes ApplicationInitialisationListener.SomeDummyEvent event) {
          }
      
          @PostConstruct
          public void init() {
              // Do something with healthCheck
          }
      
          @PreDestroy
          public void destroy() {
              // Do some other thing with healthCheck
          }
      }
      

      参考文献:

      http://struberg.wordpress.com/tag/cdi/

答案 1 :(得分:0)

现在,使用deltaspike servlet模块

这一切都很容易
@ApplicationScoped
public class InitializationResourceBean {

 @Inject
 HealthCheck healthCheck;

  public void onCreate(@Observes @Initialized ServletContext context) {
    //Do initialisation stuff here.
    if(HealthCheck != null) {
      ;
    }
  }
  public void onDestroy(@Observes @Destroyed ServletContext context) {
    System.out.println("Destroyed ServletContext: " + context.getServletContextName());
  }

}

http://deltaspike.apache.org/documentation/servlet.html

答案 2 :(得分:0)

来自:http://docs.jboss.org/weld/reference/latest-master/en-US/html/environments.html#_tomcat

&#34;支持Tomcat 7和8。上下文激活/取消激活以及依赖注入Servlet和过滤器是开箱即用的。注入Servlet监听器适用于Tomcat 7.0.50及更高版本。&#34;

那么也许你可以升级你的Tomcat?