Java 为什么Weld说;不支持向侦听器中注入";关于雄猫?

Java 为什么Weld说;不支持向侦听器中注入";关于雄猫?,java,tomcat,servlets,resteasy,weld,Java,Tomcat,Servlets,Resteasy,Weld,我有一个使用Resteasy的web项目(它反过来又使用Weld),并部署到Tomcat7.0.22(我在这里放置了特定的版本,以防这个问题是这个版本特有的) 我有一个ServletContextListener,如下所示: @WebListener public class ApplicationInitialisationListener implements ServletContextListener { // create a logger here

我有一个使用Resteasy的web项目(它反过来又使用Weld),并部署到Tomcat7.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
INFO pool-2-thread-1 org.jboss.weld.environment.tomcat7.Tomcat7Container-检测到tomcat7,CDI注入将在servlet和过滤器中提供。不支持注入到侦听器中
问题1:为什么CDI注入在监听器中不可用

我查看了一下,它说,
通过@startup在启动时加载。CDI中目前没有与此等效的产品。

问题2:问题1中所述的问题是否由此产生

问题3:我正在使用
org.jboss.weld.servlet:weld servlet:1.2.0.Beta1
。在更高版本中是否有启动支持更新

我查看的相关问题

我发现了一个变通方法,可以在应用程序启动时注入CDIBean

该问题的要求可概括为:

  • 在应用程序启动时注入CDIBean
  • 用豆子做点什么
  • 解决方案轮廓线:

  • 创建一个WebListener,调用
    BeanManager.fireEvent(新的SomedMyEvent())
  • 创建一个ApplicationScoped bean,该bean响应
    SomedMyEvent
    ,并注入CDIBean
  • 示例代码:

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

    参考资料:


    现在,使用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());
      }
    
    }
    

    来自:

    “支持Tomcat 7和8。上下文激活/停用和向Servlet和筛选器中注入依赖项都是现成的。向Servlet侦听器中注入依赖项在Tomcat 7.0.50和更高版本上都是现成的。”


    因此,也许您可以升级Tomcat?

    至于问题3:请注意,消息中说它不受CDI支持,即CDI规范没有定义这一点。这可能会添加到未来的版本中,从而添加到任何实现该未来CDI版本的Weld版本中。@Thomas CDI不是特定于servlet的,因此它不会定义任何与Java EE环境中的注入相关的内容。这是一个焊接和JSR 299功能。@SotiriosDelimanolis啊,是的,你是对的。συγνώμη :)
    @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());
      }
    
    }