将JAX-RS与CDI集成的正确方法? [英] Correct way to Integrate JAX-RS with CDI?

查看:261
本文介绍了将JAX-RS与CDI集成的正确方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经在Jersey REST资源中集成Service和DAO bean,在 @Path 注释它们javaee / 7 / tutorial / jaxrs-advanced004.htmrel =nofollow noreferrer> Java EE教程

I used to integrate Service and DAO beans in Jersey REST resources by annotating them with @Path following Java EE tutorial


一般情况,要使JAX-RS与企业bean一起使用,您需要使用@Path注释bean的类以将其转换为根资源类。您可以将@Path注释与无状态会话bean和单例POJO bean一起使用。

In general, for JAX-RS to work with enterprise beans, you need to annotate the class of a bean with @Path to convert it to a root resource class. You can use the @Path annotation with stateless session beans and singleton POJO beans.

所以我的代码曾经是这样的:

So my code used to be something like this:

@Path("/")
public class ServiceResource {
   @Inject
   private AccountService accountService;

   @GET
   @Path("/account/get")
   public Account getAccount(@QueryParam("id") String id) {
     return accountService.get(id);
   }
}

@javax.inject.Singleton
@Path("")
public class AccountService {
   public Account get(String id){...}
}

现在,我开始集成Quartz Job进入我的应用程序,我想找到一种方法在这样的工作中注入我的 AccountService

Now, I started integrating a Quartz Job into my application, and I wanted to find a way to inject my AccountService inside a job like this

public class AccountJob implements Job {
  @Inject
  private AccountService accountService;

  @Override
  public void execute(JobExecutionContext jec) throws JobExecutionException {
    accountService.updateAllAccounts();
  }
}

我发现这是answer 告诉我们使用 DeltaSpike 来做Job,所以我将以下依赖项添加到我的 pom.xml ,并且不向任何类添加任何代码行 accountService 到我的工作工作正常

I found this answer that tells to use DeltaSpike to do the Job, so I added the following dependencies to my pom.xml, and without adding any more lines of code to any class the inejection of accountService to my Job works fine

<dependency>
    <groupId>org.apache.deltaspike.modules</groupId>
    <artifactId>deltaspike-scheduler-module-api</artifactId>
    <version>1.7.2</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.apache.deltaspike.modules</groupId>
    <artifactId>deltaspike-scheduler-module-impl</artifactId>
    <version>1.7.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.apache.deltaspike.cdictrl</groupId>
    <artifactId>deltaspike-cdictrl-api</artifactId>
    <version>1.7.2</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.apache.deltaspike.cdictrl</groupId>
    <artifactId>deltaspike-cdictrl-weld</artifactId>
    <version>1.7.2</version>
    <scope>runtime</scope>
</dependency>

但是,我意识到当我删除 @Path()来自 AccountService ,其实例仍在 ServiceResource ,所以我的问题如下:

However, I realized that when I remove the @Path("") from AccountService, its instance is still injected fine inside ServiceResource, so my questions are the following:


  1. 为什么添加 DeltaSpike 依赖关系使它成为现实可以在不使用 @Path 的情况下注入我的bean吗?

  2. 通过搜索更多,我明白了 DeltaSpike 在内部使用 Weld 进行注射,因为我已经在使用 GlassFish 4.0 ,我知道 Weld 已经存在,那么为什么注入在我的 Job 类和 ServiceResource 类没有在我的bean上添加 @Path ?实际上为什么在Java教程中甚至会建议添加 @Path

  3. 是否有任何不良副作用,我没有看到我的代码,因为我认为我在这里混合了多种DI方法而没有真正了解它们是如何工作的?

  1. Why adding DeltaSpike dependencies made it possible to inject my beans without using @Path on them?
  2. By searching more, I understood that DeltaSpike internally uses Weld to do the injection, and since I am already using GlassFish 4.0, I know that Weld is already there, so why the injection is not working by default in my Job class and in ServiceResource class without adding @Path on my beans? Actually why adding @Path is even suggested in the Java tutorial?
  3. Is there any bad side effects that I don't see in my code, because I think that I am mixing multiple DI methods here without really understanding how do they work?

更新: 经过更多搜索后,我意识到 Jersey 不使用 Weld 进行依赖注入,而是使用 HK2 ,当我尝试注入<$ c $时,一个不同的框架也恰好是 GlassFish 的一部分c> AccountService 不使用 @Path 它显示以下异常

Update: After more search, I realize that Jersey doesn't use Weld for dependency injection, instead it uses HK2, a different framework that also happens to be a part of GlassFish, when I try to inject AccountService without using @Path it shows the following exception


org.glassfish.hk2.api.UnsatisfiedDependencyException:SystemInjecteeImpl没有可用于注入的对象(r​​equiredType = AccountService ,parent = ServiceResource ,qualifiers = {} ...

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=AccountService,parent=ServiceResource,qualifiers={}...

所以这会将问题更新为以下内容:

So this updates the questions to the following:


  1. 如何使 HK2 注射有效? //不使用Java EE教程中提到的 @Path

  2. 如果我设法做 DI HK2 ,使用 DeltaSpike 安全 DI 用于Quartz Job?是否可以将两个CDI framewroks混合在一起扫描类并进行注入?

  1. How to make HK2 injections works? // Without using @Path as mentioned in the Java EE Tutorial
  2. If I managed to to do DI with HK2, will it be safe to use DeltaSpike to do DI for the Quartz Job? Is it okay to mix two CDI framewroks together to scan the classes and do the injection?

我将我的源代码放在pastebin上; pom.xml 此处 Java 此处

I put my my source code on pastebin; pom.xml is here and the Java is here

推荐答案

您不需要在 AccountService 路径注释> CDI bean。如果在您的应用程序上启用了CDI(CDI 1.0中的空beans.xml或CDI> 1.0中的discovery-mode = all),则可以 @Inject 中的任何CDI bean您的JAX-RS资源。
所以你只需要编写以下课程:

You do not need to set the Path annotation on your AccountService CDI bean. If CDI is enabled on your application (either with empty beans.xml in CDI 1.0 or discovery-mode=all in CDI > 1.0), you can @Inject any CDI bean in your JAX-RS resource. So you just have to write the following class:

@Path("/")
public class ServiceResource {
   @Inject
   private AccountService accountService;

   @GET
   @Path("/account/get")
   public Account getAccount(@QueryParam("id") String id) {
     return accountService.get(id);
   }
}

@javax.inject.Singleton
public class AccountService {
   public void Account get(String id){...}
}

您在帖子中链接的文章涉及混合EJB和CDI注释。例如,您可以混合 @Stateless @Path 注释。这很有趣,例如因为你可以:

The article you linked in your post deals with mixing EJB and CDI annotations. For example you can mix @Stateless and @Path annotations. It's interesting for example because you can :


  • 您的Rest资源中的EJB事务的好处(即使现在您可以使用 @Transactional 拦截器绑定)

  • 设置资源池

  • 等。

  • Benefit of EJB transaction in your Rest resource (even if now you can use @Transactional interceptor binding)
  • Set a pool of resources
  • etc.

请注意,所有这些都没有deltaspike依赖的帮助。

Note that all of this works without the help of deltaspike dependency.

对于你的第二个问题,作为Quartz管理自己的线程,类不由CDI处理,因此您不能在Quartz类中注入bean。 deltaspike模块的目的是允许在Quartz Jobs中注入CDI bean。在内部,deltaspike控制CDI上下文。

For your second question, as Quartz manages its own threads, classes are not handled by CDI so you can not inject beans in Quartz classes. The aim of the deltaspike module is to allow injecting CDI beans in Quartz Jobs. Internally, deltaspike controls CDI Contexts.

编辑

对于您的上一个问题:

For your last questions:


  • 您的HK2问题非常肯定来自缺少的依赖项(在您的应用程序或服务器中)。正如之前的评论中所述,我设法使用您提供的源文件在Glassfish 4(内部版本89)上部署您的应用程序。

  • Your HK2 problem comes pretty sure from a missing dependency (in your application or server). As said in a previous comment, I managed to deploy your App on Glassfish 4 (build 89) with the source files you provided.

关于CDI的集成使用Quartz,我认为最好是实现自己的 JobFactory 并使用 BeanManager 实现你的作业。请看这个链接: https://devsoap.com/注入-cdi-managed-beans-into-quarz-jobs /

Regarding the integration of CDI with Quartz, I think the best is to implement your own JobFactory and instanciate your jobs using BeanManager. Take a look at this link : https://devsoap.com/injecting-cdi-managed-beans-into-quarz-jobs/

这篇关于将JAX-RS与CDI集成的正确方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆