依赖项注入未按预期工作(Tomcat9、Weld、RESTEasy)
我正在基于运行在Tomcat9上的JAX-RS构建一个Java web应用程序,我想使用依赖项注入来实例化对象 奇怪的是,当我在依赖项注入未按预期工作(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调用调用。这
监听器
类(用@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();
}
}