【问题标题】:jersey 2.0 :: for cdi injection, is beans.xml mandatory?jersey 2.0 :: 对于 cdi 注入,beans.xml 是强制性的吗?
【发布时间】:2015-06-08 13:25:36
【问题描述】:

资源类

public class UploadFileService {

    @Inject public Logger logger;

    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(
        @FormDataParam("file") InputStream uploadedInputStream,
        @FormDataParam("file") FormDataContentDisposition fileDetail) {
    }
}

注入 :: Logger 类

@Dependent
public final class Loggers {

    @Produces
    public static final Logger getLogger(final InjectionPoint injectionPoint) {
    if (injectionPoint == null) {
        throw new IllegalArgumentException("injectionPoint", new NullPointerException("injectionPoint"));
    }
}

注入在包含 beans.xml 时完美工作

*.war\WEB-INF\classes\META-INF\beans.xml

但是在 jersey 2.0 中不是 beans.xml 可选吗?

没有beans.xml报错

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=Logger,parent=UploadFileService,
qualifiers={},position=-1,optional=false,self=false,unqualified=null,1642832267)
        at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
        at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:947)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:902)
        at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider$CdiFactory$2.getInstance(CdiComponentProvider.java:245)
        at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider$CdiFactory.provide(CdiComponentProvider.java:189)

任何澄清是有帮助的?

【问题讨论】:

  • public final class Loggers 上的那个额外的 's' 只是一个错字,我希望?顺便说一句,these answers 中的任何一个有帮助吗?单例 bean 是一种代码味道......
  • 没有。我担心的是......为什么在这种特殊情况下需要一个空 beans.xml 文件,而它在 jersey 2.0 中是可选的?
  • 内容是可选的,但带有基本<beans>的文件是必需的。不要问为什么;当我上次使用 Jersey 和 CDI 时,需要 很多 诡计才能让它工作......

标签: java cdi jersey-2.0


【解决方案1】:

您的问题的答案取决于CDI 的版本。

CDI 1.0

对于 CDI 的 1.0 版,beans.xml 是启用 CDI bean 发现所必需的。如果没有beans.xmlCDI 在相应的存档中根本不活动。

来自 CDI 1.1

从 CDI 1.1 开始,beans.xml 不再是强制性的。扫描如下:

  • 省略 beans.xml 或设置 bean-discovery-mode="annotated",会使存档成为隐式存档。在这种情况下,容器将扫描带有注解作用域类型的 bean。
  • 设置bean-discovery-mode="all",将扫描所有类。

所以在你的情况下,如果你想让 Jersey 2.0 在没有 beans.xml 的情况下工作,假设 CDI 版本至少为 1.1,你可以用范围注释你的 Rest 资源,通常是 @RequestScoped

@RequestScoped
public class UploadFileService {

    @Inject 
    private Logger logger;

    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(
        @FormDataParam("file") InputStream uploadedInputStream,
        @FormDataParam("file") FormDataContentDisposition fileDetail) {
    }
}

但如果您使用 CDI 1.0,那么是的,您将需要 beans.xml

【讨论】:

    【解决方案2】:

    是的,CDI 1.1 需要 beans.xml 文件。

    放置它们的位置可能会因您的包装风格而异。因此,如果您要进行战争,那么 beans.xml 应该存在于 WEB-INF 文件夹中。

    对于为什么重要的问题..

    beans.xml 文件在指定位置的存在有助于 CDI 容器进行类路径扫描。

    beans.xml 在 Jersey 中是可选的,因为它使用 hk2 进行依赖注入。但我个人认为 CDI 1.1 比 hk2 更健壮和强大,所以我们应该使用 CDI 1.1 或更好的 CDI 2.0(因为它有很多改进)。

    如果您好奇,请随时查看 CDI 2.0 示例(不带运动衫)https://github.com/NajeebArif/CDI-2.0-Example

    【讨论】:

    • beans.xml 从 CDI 1.1 开始不是强制性的。在这种情况下,只会扫描具有范围类型的注释类
    • @Rouliboy ya 我试过了,但发现了一些不一致的错误。我无法指出确切的原因,但你肯定会在未来的版本中解决这些问题。通常我使用 jDeveloper 和 Weblogic 12c,所以发现那里的不一致。不过感谢您的回复。
    猜你喜欢
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 1970-01-01
    相关资源
    最近更新 更多