【问题标题】:CDI doesn't work in a simple adapterCDI 在简单的适配器中不起作用
【发布时间】:2019-01-23 13:23:37
【问题描述】:

我已将 CDI 功能添加到 server.xml 文件<feature>cdi-1.2</feature>

我的 maven 模块在 <module_name>/src/main/resources/META-INF 文件夹中包含 beans.xml

这是 beans.xml 内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                           http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">
</beans>

但是当我使用 @Inject 注释时它不起作用,我的 bean 始终是 null

代码:

package ch.webapp.presentation;

...

@Path("/test/")
public class MyController {
    @Inject
    private MyService myService;

    @GET
    @Path("/foo/{count}")
    @OAuthSecurity(scope = "login")
    @Produces("application/json")
    public Response news(@PathParam("count") int count) {
        return Response
                .ok(myService.getBar(count))
                .build();
    }
}

编辑:

那是我的豆

package ch.webapp.service;

...

@RequestScoped
public class MyService {
    public String getBar(int count) {
        return "foo";
    }
}

我通过扩展 MFPJAXRSApplication 类来初始化 jax-rs

package ch.webapp;

...

public class AccountApplication extends MFPJAXRSApplication {
    @Override
    protected void init() throws Exception {
    }

    @Override
    protected void destroy() throws Exception {
    }

    @Override
    protected String getPackageToScan() {
        return getClass().getPackage().getName();
    }
}

环境详情:

Launching mfp (WebSphere Application Server 8.5.5.8/wlp-1.0.11.cl50820151201-1942) on Java HotSpot(TM) 64-Bit Server VM, version 1.8.0_172-b11 (en_CH)

Console Product version: 8.0.0.00-20180717-175523

怎么了?

【问题讨论】:

  • MyService 定义为 CDI bean 还是有明确的生产者 (@Produces) 方法?
  • (要将MyService 定义为CDI bean,您只需将@ApplicationScoped@RequestScoped 放在MyService 类上)
  • MyService 类被注释为@Stateless
  • 您确定为 JAX-RS 资源激活了 CDI 吗?它可能需要一些额外的配置(我不知道,因为我不知道 Websphere)。是MyService@Stateless,还是@RequestScoped?两者兼有没有多大意义!它与MyController 位于同一个jar 中吗?如果没有,jar 中是否有包含MyService 的 beans.xml?还要确保@RequestScopedjavax.enterprize.context 而不是javax.faces.bean 下的那个!
  • 您是否以通常的方式直接通过 http 客户端访问资源?我想确定您不是自己构建 MyController。

标签: ibm-mobilefirst cdi websphere-liberty mobilefirst-adapters open-liberty


【解决方案1】:

首先,websphere jax-rs 实现似乎不会自动集成 jax-rs 资源,除非您对它们进行适当的注释。

通过适当注释将 jax-rs 放入 CDI 托管上下文中

@Path("/test/")
@javax.enterprise.context.RequestScoped
public class MyController {

    @Inject
    private MyService myService;

    @GET
    @Path("/foo/{count}")
    @OAuthSecurity(scope = "login")
    @Produces("application/json")
    public Response news(@PathParam("count") int count) {
        return Response
                .ok(myService.getBar(count))
                .build();
    }

}

还要确保用于您的服务的注释是 @javax.enterprise.context.RequestScoped

【讨论】:

    【解决方案2】:

    这是典型的错误。 CDI 适用于 托管 bean(例如 EJB 和 servlet)。如果您想在您的 JAXRS bean 上启用它,您必须将其设为“托管”,即将 MyController 注释为 (for instance) javax.annotation.ManagedBeanjavax.ejb.Stateless

    还要注意,对于 webapp (.war),beans.xml 文件必须位于 WEB-INF 文件夹中!

    【讨论】:

    • 您阅读了哪篇关于 ManagedBean 注解的教程?我见过的每个教程都没有这样做。甚至原始的“oracle”教程javaee.github.io/tutorial/jaxrs-advanced004.html 也声明要执行其他答案中已完成的操作(或像您一样添加无状态)
    • 那是教程的问题。他们给出了一些例子,但没有清楚地解释这些原则。如果你想将 bean 注入到一个 bean 中,你的 bean 必须成为“cdi-aware”。 JAX-RS bean(资源)默认不是 CDI bean,您必须添加注释以允许注入。您有许多不同的可能注释(Stateless、Stateful、Singleton、RequestScoped、ApplicationScoped 等),其中之一(实际上是最基本的)是 javax.annotation.ManagedBean。
    • 请阅读文档 (docs.oracle.com/javaee/6/api/javax/annotation/ManagedBean.html):“ManagedBean 注解将 POJO(普通旧 Java 对象)标记为 ManagedBean。ManagedBean 支持一小组基本服务,例如资源注入”。
    【解决方案3】:

    根据您提供的信息,请查看以下清单。

    1. 你的服务和控制器在同一个模块,它的封装类型是war,所以你必须把你的beans.xml放在这个路径src/main/resources/WEB-INF/beans.xml中。 (如果这是 Java EE 7 应用程序,则 beans.xml 是可选的。
    2. 在您的 AccountApplication 类中,尝试将包名硬编码为 ch.webapp.presentation

      @覆盖 受保护的字符串 getPackageToScan() { 返回“ch.webapp.presentation”; }

    这只是为了检查 MFPJAXRSApplication.getPackageToScan() 方法的行为是只扫描指定的包还是它的子包。

    1. 除了这些,我觉得一切都很好。如果这仍然不起作用,请添加完整的应用程序启动日志,以便社区可以找到它的根本原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 2014-05-07
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多