我曾经在Jersey REST资源中集成Service和DAO bean,并在Java EE tutorial之后使用@Path
注释它们
通常,要使JAX-RS使用企业bean,您需要使用@Path注释bean的类以将其转换为根资源类。您可以将@Path注释与无状态会话bean和单例POJO bean一起使用。
所以我的代码曾经是这样的:
@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
注入到这样的工作中
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
对我的Job
的拒绝工作正常
<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
内注入正常,所以我的问题如下:
DeltaSpike
依赖项可以在不使用@Path
的情况下注入我的bean?DeltaSpike
内部使用Weld
进行注入,因为我已经在使用GlassFish 4.0
,所以我知道Weld
已经存在那么为什么注入在我的Job
类和ServiceResource
类中默认不起作用而不在我的bean上添加@Path
?实际上为什么在Java教程中甚至会建议添加@Path
? 更新:经过更多搜索,我发现Jersey
没有使用Weld
进行依赖注入,而是使用HK2
,不同的框架也恰好是GlassFish
的一部分,当我尝试在不使用AccountService
的情况下注入@Path
时,它会显示以下异常
org.glassfish.hk2.api.UnsatisfiedDependencyException:SystemInjecteeImpl没有可用于注入的对象(requiredType = AccountService ,parent = ServiceResource ,qualifiers = {}。 ..
所以这会将问题更新为以下内容:
答案 0 :(得分:4)
您无需在this.countryServices = [];
let data = [
{country: 'Spain', services: ['spainSservice1', 'spainService2']},
{country: 'Canada', services: ['canadaservice1', 'canadaservice2']},
];
data.map(country => {
this.countryServices.push(country.country);
country.services.map(service => {
this.countryServices.push(service);
})
});
CDI bean上设置<select>
<option *ngFor="let cs of countryServices" [ngValue]="cs">{{cs}}</option>
</select>
注释。如果在您的应用程序上启用了CDI(在CDI 1.0中使用空beans.xml或在CDI&gt; 1.0中使用discovery-mode = all),则可以在{JAX-RS资源中Path
任何CDI bean。
所以你只需要编写以下类:
AccountService
您在帖子中链接的文章涉及混合EJB和CDI注释。例如,您可以混合使用@Inject
和@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){...}
}
注释。这很有趣,例如因为你可以:
@Stateless
拦截器绑定)请注意,所有这些都可以在没有deltaspike依赖的帮助下工作。
对于第二个问题,由于Quartz管理自己的线程,因此CDI不会处理类,因此您无法在Quartz类中注入bean。 deltaspike模块的目的是允许在Quartz Jobs中注入CDI bean。在内部,deltaspike控制CDI上下文。
修改强>
关于你的上一个问题:
您的HK2问题非常肯定来自缺少的依赖项(在您的应用程序或服务器中)。正如之前的评论中所述,我设法使用您提供的源文件在Glassfish 4(版本89)上部署您的应用程序。
关于CDI与Quartz的集成,我认为最好是实现自己的@Path
并使用@Transactional
实现您的工作。请看一下这个链接:https://devsoap.com/injecting-cdi-managed-beans-into-quarz-jobs/
答案 1 :(得分:1)
首先注入的资源(bean)和Jersey Endpoint类(注入点)必须是CDI-Aware。必须由CDI检测。我们可以使用bean-discovery-mode =“all” - 然后CDI扫描所有类或 bean-discovery-mode =“annotated”并使用PROPER注释标记我们的类:从这里:Bean defining annotations。我更喜欢@Dependent或@RequestScoped
然后我们必须使用Jersey Extension
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-cdi1x-servlet</artifactId>
<version>{version}</version>
<scope>runtime</scope>
</dependency>
`
将CDI与HK2发现机制连接起来。 这是Official oracle Guideline
答案 2 :(得分:-1)
默认的beans.xml发现模式(在Java EE 7中)是#34;注释&#34;。这意味着只有具有CDI注释的bean才能被CDI识别和管理。
您的AccountJob类未注释。如果您希望CDI能够将服务注入其中,那么您需要使用一些范围注释来注释它,例如: @ApplicationScoped。
您的另一个选择是创建用于创建AccountJob bean的CDI生产者。看到: http://docs.jboss.org/weld/reference/latest/en-US/html_single/#_producer_methods