gpt4 book ai didi

java - 在 ResourceContext initResource 创建的 JAX-RS 子资源实例中不可能进行 CDI 注入(inject)

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:16:31 24 4
gpt4 key购买 nike

我有一个 JAX-RS 资源类,它使用 @Context ResourceContext 为每个资源类型创建子资源实例,提供到子资源类的路径路由。在这个例子中,我正在实例化一个报告子资源。

资源

@Context
ResourceContext rc;

@Path("reports")
public ReportsResource reportsResource() {
return rc.initResource(new ReportsResource());
}

子资源需要一个 ReportService 类的实例(用 @Stateless 注释定义),自然的解决方案是 @Inject 它 ...

报告子资源

@Inject
ReportsService rs;

@GET
@Path("{rptno}")
@Produces(MediaType.APPLICATION_XML)
public Report report(@PathParam("rptno") int rptNumber) throws Exception {
return rs.getReport(rptNumber);
}

我将 Java EE7 与 Glassfish 和 WAS Liberty Profile 结合使用的经验是没有注入(inject) ReportService rs 的实例,导致 rs 为 null 并导致 NPE。

我的假设是,由于资源类正在执行“new ReportsResource()”,CDI 对 ReportsResource 实例不可见,因此 ReportsResource 不是容器管理的。这好像和这个问题一样的情况Inject EJB into JAX-RS 2.0 subresource when subresource is got via ResourceContext

我的解决方案有些不同,我选择在 Resource 类中 @Inject ReportService,然后将实例传递给 ReportsResource 构造函数。

修改后的资源

@Inject
ReportsSerivce rs;

@Context
ResourceContext rc;

@Path("reports")
public ReportsResource reportsResource() {
return rc.initResource(new ReportsResource(rs));
}

修改后的报告子资源

public class ReportsResource {
private ReportsSerivce rs;

public ReportsResource(ReportsSerivce rs) {
this.rs = rs;
}

@Context
HttpHeaders headers;

@GET
@Path("{rptno}")
@Produces(MediaType.APPLICATION_XML)
public Report report(@PathParam("rptno") int rptNumber) throws Exception {
return rs.getReport(rptNumber);
}

所以我的问题

  1. 我关于@Inject 失败原因的假设是否正确?
  2. 有没有办法让@Inject在子资源中起作用?
  3. 是否有更好的解决方案来将 ReportService 实例从 Resource 传递到更像“CDI/Java EE”的 SubResource?

最佳答案

如果您想将 CDI bean 注入(inject)到 JAX-RS 资源中,我不建议使用 rc.initResource .它所做的只是将字段注入(inject)现有对象,但它使用 JAX-RS 特定机制,类似于在 CDI 不可用时在 JavaEE5 中为 EJB 注入(inject)的方式。

最好使用 CDI 并从代码中删除 ResourceContext

例子:

资源

@Inject
private ReportsResource reportsResource;

@Path("reports")
public ReportsResource reportsResource() {
return reportsResource;
}

主资源应该是@RequestScoped 以便为每个请求重新创建它。或者你可以使用 Intance 注入(inject)为每个方法调用获取新实例:

@Inject
private Instance<ReportsResource> reportsResources;

@Path("reports")
public ReportsResource reportsResource() {
return reportsResources.get();
}

关于java - 在 ResourceContext initResource 创建的 JAX-RS 子资源实例中不可能进行 CDI 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36122079/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com