CDI 注入源在 Jersey 子资源中不可用
CDI injection source not available in Jersey sub-resource
我在 Jersey 应用程序中使用 CDI。在根资源上,CDI 注入按预期工作,但每当我 return 子资源时,CDI 注入源不可用。
我的带有子资源定位器的根资源:
@Path("")
public class MyResource {
@Inject @Named("name") // works
private String name;
@Context
private ResourceContext context;
@Path("test2")
public Object test2() {
return MySubResource.class;
//return context.getResource(MySubResource.class); // this does not work either
}
}
子资源:
public class MySubResource {
@Inject @Named("name") // error
private String name;
@GET
public Response test() {
return Response.ok("Name in sub resource: " + name).build();
}
}
错误:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=String,parent=MySubResource,qualifiers={@javax.inject.Named(value=name)},position=-1,optional=false,self=false,unqualified=null,1235803160)
我在 Undertow 上使用 org.glassfish.jersey.ext.cdi:jersey-cdi1x
和 Weld 依赖项,运行,并将 Weld servlet 侦听器添加到部署中。
同样,对根资源的相同注入 确实 有效。 @Named("name") String
由 @ApplicationScoped
生产者生产。
这行不通吗?我错过了什么?
此处提供最小示例 Maven 项目:
https://gitlab.com/Victor8321/jersey-sub-resource-cdi
注意:存在一个未解决的问题,但不确定官方对此的立场是什么:https://java.net/jira/browse/JERSEY-3184
正如 https://github.com/eclipse-ee4j/jersey/issues/3456 中指出的那样,向子资源 class 添加虚拟 @Path("xyz")
是一个“修复”。但是,这会将您的子资源暴露在虚拟路径下。
仅通过 CDI 注入实例也可以(@Inject Instance<MySubResource> ..
),但是 Jersey 管理的资源不可用于注入,例如 @Context HttpServletRequest
.
我发现了另外 2 种完全有效的方法(CDI 注入和 JAX-RS 注入)并且没有副作用(与 @Path
一样):
- 将子资源class注释为
@Provider
。
register()
ResourceConfig
(或Application
)中的子资源class。
这两种方法似乎都有效,因为它们使泽西岛 - 进而使 CDI - 意识到 class。
注意:我已经相应地更新了我的示例项目以供将来参考。
我在 Jersey 应用程序中使用 CDI。在根资源上,CDI 注入按预期工作,但每当我 return 子资源时,CDI 注入源不可用。
我的带有子资源定位器的根资源:
@Path("")
public class MyResource {
@Inject @Named("name") // works
private String name;
@Context
private ResourceContext context;
@Path("test2")
public Object test2() {
return MySubResource.class;
//return context.getResource(MySubResource.class); // this does not work either
}
}
子资源:
public class MySubResource {
@Inject @Named("name") // error
private String name;
@GET
public Response test() {
return Response.ok("Name in sub resource: " + name).build();
}
}
错误:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=String,parent=MySubResource,qualifiers={@javax.inject.Named(value=name)},position=-1,optional=false,self=false,unqualified=null,1235803160)
我在 Undertow 上使用 org.glassfish.jersey.ext.cdi:jersey-cdi1x
和 Weld 依赖项,运行,并将 Weld servlet 侦听器添加到部署中。
同样,对根资源的相同注入 确实 有效。 @Named("name") String
由 @ApplicationScoped
生产者生产。
这行不通吗?我错过了什么?
此处提供最小示例 Maven 项目: https://gitlab.com/Victor8321/jersey-sub-resource-cdi
注意:存在一个未解决的问题,但不确定官方对此的立场是什么:https://java.net/jira/browse/JERSEY-3184
正如 https://github.com/eclipse-ee4j/jersey/issues/3456 中指出的那样,向子资源 class 添加虚拟 @Path("xyz")
是一个“修复”。但是,这会将您的子资源暴露在虚拟路径下。
仅通过 CDI 注入实例也可以(@Inject Instance<MySubResource> ..
),但是 Jersey 管理的资源不可用于注入,例如 @Context HttpServletRequest
.
我发现了另外 2 种完全有效的方法(CDI 注入和 JAX-RS 注入)并且没有副作用(与 @Path
一样):
- 将子资源class注释为
@Provider
。 register()
ResourceConfig
(或Application
)中的子资源class。
这两种方法似乎都有效,因为它们使泽西岛 - 进而使 CDI - 意识到 class。
注意:我已经相应地更新了我的示例项目以供将来参考。