7

我有一个使用 Resteasy(又使用 Weld)的 Web 项目,并部署到 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注入在Listeners中不可用?

我查看了这个答案,它说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 中查看了启动课程

4

3 回答 3

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 {
    }
}

@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/

于 2013-11-21T12:34:53.967 回答
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

于 2014-02-20T12:10:12.277 回答
0

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

“支持 Tomcat 7 和 8。上下文激活/停用和依赖注入 Servlet 和过滤器开箱即用。注入 Servlet 侦听器在 Tomcat 7.0.50 及更高版本上工作。”

所以也许你可以升级你的Tomcat?

于 2015-09-16T10:48:36.773 回答