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

sta*_*wer 7 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) {
    }
}
Run Code Online (Sandbox Code Playgroud)

在部署到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
Run Code Online (Sandbox Code Playgroud)

问题1:为什么CDI注入在监听器中不可用?

我调查了这个答案,然后说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.在以后的版本中是否有关于启动支持的更新?

相关问题我 在Weld 看过启动课程

sta*_*wer 1

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

问题的要求可以概括为:

  1. 应用程序启动时注入 CDI bean
  2. 用豆子做点什么

解决方案概要线:

  1. 创建一个调用的 WebListenerBeanManager.fireEvent(new SomeDummyEvent())
  2. 创建一个响应SomeDummyEvent并注入 CDI bean 的ApplicationScoped bean

示例代码:

@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 {
    }
}
Run Code Online (Sandbox Code Playgroud)
@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
    }
}
Run Code Online (Sandbox Code Playgroud)

参考:

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