依赖项注入未按预期工作(Tomcat9、Weld、RESTEasy)

依赖项注入未按预期工作(Tomcat9、Weld、RESTEasy),tomcat,jax-rs,cdi,resteasy,weld,Tomcat,Jax Rs,Cdi,Resteasy,Weld,我正在基于运行在Tomcat9上的JAX-RS构建一个Java web应用程序,我想使用依赖项注入来实例化对象 奇怪的是,当我在监听器类(用@WebListener注释的类)中使用@Inject时,注入工作正常。当我在REST端点(由@Path注释的类)内使用@Inject时,注入不起作用,我得到NullPointerException 我的问题:有人能向我解释为什么CDI在这些不同的环境中表现不同吗 侦听器代码在服务器启动期间执行。端点代码必须由/hello上的传入HTTP GET调用调用。这

我正在基于运行在Tomcat9上的JAX-RS构建一个Java web应用程序,我想使用依赖项注入来实例化对象

奇怪的是,当我在
监听器
类(用
@WebListener
注释的类)中使用
@Inject
时,注入工作正常。当我在REST端点(由
@Path
注释的类)内使用
@Inject
时,注入不起作用,我得到NullPointerException

我的问题:有人能向我解释为什么CDI在这些不同的环境中表现不同吗

侦听器代码在服务器启动期间执行。端点代码必须由
/hello
上的传入HTTP GET调用调用。这将指向两个示例的不同范围。但是,尝试用任何范围注释标记正在注入的类没有帮助

另外,当我尝试从REST端点类调用
CDI.current().select(HelloProvider.class).get()
时,我会从CDI获取一个有效的提供者实例

以下是我的设置的一些详细信息:

pom.xml

侦听器实现

@Path("/hello")
public class HelloEndpoint {

  @Inject
  private HelloProvider provider;
  
  @GET
  public Response getHello() {   
    System.out.println("enpoint says: " + provider.getHello()); // throws NPE
    HelloProvider instance = CDI.current().select(HelloProvider.class).get(); // this give me the provider instance
    return Response.ok().build();
  }
}
端点实现

@Path("/hello")
public class HelloEndpoint {

  @Inject
  private HelloProvider provider;
  
  @GET
  public Response getHello() {   
    System.out.println("enpoint says: " + provider.getHello()); // throws NPE
    HelloProvider instance = CDI.current().select(HelloProvider.class).get(); // this give me the provider instance
    return Response.ok().build();
  }
}

尝试用@RequestScope()注释资源类。默认情况下,资源类(HelloEndpoint)实际上获取RequestScope,即使没有明确指定它。下面是来自Weld的一段跟踪日志:
TRACE 2020-11-26T19:33:00098[Bean]-Weld-000016:使用作用域接口javax.enterprise.context.requestScope为托管Bean[class com.test.HelloEndpoint]和限定符[@Any@Default]
。因此,显式地添加它在注入过程中没有任何区别。请尝试使用@RequestScope()注释资源类。默认情况下,资源类(HelloEndpoint)实际上会获取RequestScope,即使没有显式地指定它。下面是来自Weld的一段跟踪日志:
TRACE 2020-11-26T19:33:00098[Bean]-Weld-000016:使用作用域接口javax.enterprise.context.requestScope为托管Bean[class com.test.HelloEndpoint]和限定符[@Any@Default]
。因此,明确添加它对注射成功没有影响
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_1.xsd" version="3.1">

  <display-name>Hello World</display-name>
</web-app> 
public class HelloProvider {

  public String getHello() {
    return "Hello";
  }
}
@WebListener
public class HelloApplicationListener implements ServletContextListener {

  @Inject
  private HelloProvider provider;
  
  @Override
  public void contextInitialized(ServletContextEvent event) {
    System.out.println("listener says: " + provider.getHello()); // works fine
  }

  @Override
  public void contextDestroyed(ServletContextEvent arg0) {}

}
@Path("/hello")
public class HelloEndpoint {

  @Inject
  private HelloProvider provider;
  
  @GET
  public Response getHello() {   
    System.out.println("enpoint says: " + provider.getHello()); // throws NPE
    HelloProvider instance = CDI.current().select(HelloProvider.class).get(); // this give me the provider instance
    return Response.ok().build();
  }
}