简体   繁体   English

JAXRS资源中的Jersey CDI注入

[英]Jersey CDI injection in JAXRS resource

Disclaimer: I'm just getting started with OSGI so please bear with me and my lack of knowledge... 免责声明:我刚刚开始使用OSGI,所以请耐心等待我和我缺乏知识......


For the sake of this exercise, suppose I have a Jersey (2.17.0) based REST application running under Jetty (9.2.10) in an OSGI environment, which provides the user with some statistics that are gathered from a separate server via SOAP. 为了这个练习,假设我在OSGI环境中有一个在Jetty(9.2.10)下运行的基于Jersey(2.17.0)的REST应用程序,它为用户提供了一些通过SOAP从单独的服务器收集的统计信息。

I'm now trying to reuse some of the existing code in a different application which is supposed to retrieve statistics via JMS (or something else). 我现在正试图在一个不同的应用程序中重用一些现有的代码,这些应用程序应该通过JMS(或其他东西)检索统计信息。

My intention is to introduce an abstraction layer for the client API in a bundle, implement a bundle for each application with the appropriate communication channel and use CDI to inject the client at runtime in my REST resources. 我的目的是为bundle中的客户端API引入一个抽象层,使用适当的通信通道为每个应用程序实现一个bundle,并使用CDI在运行时在我的REST资源中注入客户端。 For example: 例如:

The REST resource (bundle 1, common for both apps) REST资源 (捆绑包1,两个应用程序通用)

@Path("statistics")
public class StatisticsResource {

    @Inject
    private StatisticsClient client;

    @GET
    @Path("users")
    public List<User> getActiveUsers(){
        return client.getActiveUsers();
    }
}

Common API (bundle 2, common for both apps) 通用API (捆绑2,两个应用程序通用)

public interface StatisticsClient {
    List<User> getActiveUsers();
}

SOAP implementation (bundle 3 for app 1) SOAP实现 (针对应用1的捆绑3)

@ApplicationScoped
public class SOAPClient implements StatisticsClient {
    @Override
    public List<User> getActiveUsers() {
        // connect to server via SOAP
    }
}

JMS implementation (bundle 3 for app 2) JMS实现 (针对应用2的捆绑3)

@ApplicationScoped
public class JMSClient implements StatisticsClient {
    @Override
    public List<User> getActiveUsers() {
        // connect to server via JMS
    }
}

I've been reading and searching for information on how to use injection with Jersey, HK2 (2.4.0) and OSGI but I so far I haven't found something relevant to match the above idea. 我一直在阅读和搜索有关如何使用Jersey,HK2(2.4.0)和OSGI注射的信息,但到目前为止,我还没有找到符合上述想法的相关内容。

Most of the Jersey CDI injection examples I've seen so far, define bindings using concrete classes, such as bind(MyService.class).to(MyService.class); 到目前为止,我见过的大多数Jersey CDI注入示例都使用具体类来定义绑定,例如bind(MyService.class).to(MyService.class); whereas I'd like to be able to switch implementation at runtime and use either SOAPClient or JMSClient depending on the application where the code is currently running. 而我希望能够在运行时切换实现并使用SOAPClientJMSClient具体取决于代码当前运行的应用程序。 Ideally the implementation would be deduced/detected by the framework from the available OSGI services (or perhaps classpath or something similar)... 理想情况下,框架将从可用的OSGI服务(或类似路径或类似的东西)推断/检测实现......

Is that doable, and if so, what am I missing? 这是可行的,如果是的话,我错过了什么? Alternatively what basic concept did I perhaps misunderstood or missed? 或者,我可能误解或错过了什么基本概念?

You can use simple EJBs with CDI producers(producers inject beans, or produces bean instances to be injected, depending on some criteria). 您可以将简单的EJB与CDI生成器一起使用(生成器注入bean,或生成要注入的bean实例,具体取决于某些条件)。

pseudo code: 伪代码:

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
}

Check this link https://docs.oracle.com/javaee/7/tutorial/cdi-adv003.htm 查看此链接https://docs.oracle.com/javaee/7/tutorial/cdi-adv003.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM