免责声明:我刚刚开始使用 OSGI,所以请容忍我和我缺乏知识......
<小时/>为了进行本练习,假设我有一个基于 Jersey (2.17.0) 的 REST 应用程序,在 OSGI 环境中的 Jetty (9.2.10) 下运行,该应用程序向用户提供一些通过 SOAP 从单独服务器收集的统计信息。
我现在尝试在不同的应用程序中重用一些现有代码,该应用程序应该通过 JMS(或其他方式)检索统计信息。
我的目的是在 bundle 中引入客户端 API 的抽象层,使用适当的通信 channel 为每个应用程序实现 bundle ,并使用 CDI 在运行时将客户端注入(inject)到我的 REST 资源中。例如:
REST 资源( bundle 1,两个应用程序共用)
@Path("statistics")
public class StatisticsResource {
@Inject
private StatisticsClient client;
@GET
@Path("users")
public List<User> getActiveUsers(){
return client.getActiveUsers();
}
}
通用 API( bundle 2,两个应用程序通用)
public interface StatisticsClient {
List<User> getActiveUsers();
}
SOAP 实现(应用 1 的 bundle 3)
@ApplicationScoped
public class SOAPClient implements StatisticsClient {
@Override
public List<User> getActiveUsers() {
// connect to server via SOAP
}
}
JMS 实现(应用程序 2 的 bundle 3)
@ApplicationScoped
public class JMSClient implements StatisticsClient {
@Override
public List<User> getActiveUsers() {
// connect to server via JMS
}
}
我一直在阅读和搜索有关如何使用 Jersey、HK2 (2.4.0) 和 OSGI 进行注入(inject)的信息,但到目前为止我还没有找到与上述想法相匹配的相关内容。
大部分泽西CDI注入(inject)examples到目前为止,我已经看到,使用具体类定义绑定(bind),例如 bind(MyService.class).to(MyService.class);
,而我希望能够在运行时切换实现,并根据当前运行代码的应用程序使用 SOAPClient
或 JMSClient
。理想情况下,框架可以从可用的 OSGI 服务(或者可能是类路径或类似的东西)中推断/检测实现...
这可行吗?如果可以,我错过了什么? 或者我可能误解或错过了哪些基本概念?
最佳答案
您可以将简单的 EJB 与 CDI 生产者一起使用(生产者注入(inject) Bean,或生成要注入(inject)的 Bean 实例,具体取决于某些条件)。
伪代码:
public interface Service;
@Stateless
@ServiceImplementation(A) //Qualifier *
public class ServiceImplA implements Service{
//impl code
}
@Stateless
@ServiceImplementation(B) //Qualifier *
public class ServiceImplB implements Service{
// impl code
}
@Produces
@ApplicationScoped
public Service produceServiceInstances(){
if(condition)
return ServiceImplA
else
return ServiceImplB
}
检查此链接 https://docs.oracle.com/javaee/7/tutorial/cdi-adv003.htm
关于java - JAXRS 资源中的 Jersey CDI 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40487869/