我在 Jersey 应用程序中使用 CDI。在根资源上,CDI 注入(inject)按预期工作,但每当我返回子资源时,CDI 注入(inject)源都不可用。
我的根资源与子资源定位器:
@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)
我正在使用org.glassfish.jersey.ext.cdi:jersey-cdi1x
和 Weld 依赖项,在 Undertow 上运行,并将 Weld servlet 监听器添加到部署中。
同样,对根资源的相同注入(inject)确实有效。 @Named("name") String
由 @ApplicationScoped
制作制片人。
这不应该起作用吗?我错过了什么?
此处提供了最小的 Maven 项目示例: https://gitlab.com/Victor8321/jersey-sub-resource-cdi
注意:存在一个 Unresolved 问题,但不确定官方对此的立场是什么:https://java.net/jira/browse/JERSEY-3184
最佳答案
正如 https://github.com/eclipse-ee4j/jersey/issues/3456 中所指出的,向子资源类添加虚拟 @Path("xyz")
是一个“修复”。但是,这会在虚拟路径下公开您的子资源。
仅通过 CDI 注入(inject)实例也可以( @Inject Instance<MySubResource> ..
),但 Jersey 管理的资源不可用于注入(inject),例如 @Context HttpServletRequest
。
我发现了另外 2 种完全有效的方法(CDI 注入(inject)和 JAX-RS 注入(inject))并且没有副作用(与 @Path
一样):
- 使用
@Provider
注释子资源类。 -
register()
ResourceConfig
(或Application
)中的子资源类。
这两种方法似乎都有效,因为它们使 Jersey - 以及 CDI - 意识到了该类。
注意:我已相应更新了我的示例项目以供将来引用。
关于java - CDI 注入(inject)源在 Jersey 子资源中不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42599173/