我有一个子资源类,必须使用路径中的参数进行初始化,并且还包含对必须注入的EJB的引用。
资源类:
@Path("widgets")
public class MasterResource{
@Inject
WidgetBean widgets;
@Context
ResourceContext rc;
@Path("{year}")
public WidgetArchives wArchives(@PathParam("year") String year){
return rc.initResource(new WidgetArchiveResource(year));
}
}
子资源类
public class WidgetArchiveResource{
@Inject
WidgetBean widgets;
public WidgetArchiveResource(String year){
....code
}
@GET
public String doGet(){
....code using WidgetBean
}
}
当我调用年份时,我看到以下错误:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=WidgetBean,parent=WidgetArchiveResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,542790913)
我是Java EE的新手。我做错了什么?
答案 0 :(得分:2)
方法rc.initResource只有在需要向资源中注入一些依赖项时才有意义(例如,由@Inject注释)。这是一种将依赖项注入bean的JAX-RS特定方法。它在完全JavaEE环境中被弃用,其中注入依赖项的首选方法是通过CDI。 rc.initResource
不会注入所有CDI bean(例如@EJB可以工作,但@Inject不能)。
因此,在JavaEE中,执行您想要实现的目标的首选方法是将WidgetArchiveResource
注入父MasterResource
。 CDI bean必须具有不带参数的构造函数,但您可以使用setter传递year。如果您将主资源放在请求范围内,则会为每个请求重新创建它,使其对并发请求安全:
@Path("widgets")
@RequestScoped
public class MasterResource{
@Inject
Instance<WidgetArchiveResource> waResources;
@Path("{year}")
public WidgetArchives wArchives(@PathParam("year") String year){
WidgetArchiveResource waResource = waResources.get();
waResource.setYear(year);
return waResource;
}
}
此外,您应该在带有bean-discovery-mode="all"
的WEB-INF文件夹中包含beans.xml,或者在WidgetArchiveResource
上明确添加相关范围以使其符合CDI条件:
@Dependent
public class WidgetArchiveResource {
public WidgetArchiveResource() {} // optional no arg constructor
}