使用带有或不带有抽象绑定的Jersey的CDI进行依赖注入 [英] Dependency Injection using CDI with Jersey with/without abstract binding

查看:199
本文介绍了使用带有或不带有抽象绑定的Jersey的CDI进行依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,这不是自以为是的问题,我已经阅读了SO中的大多数相关问题.我正在寻求建议,以下实施的解决方案是否是正确的方法/方法.

First of all, this is not opinionated question and I have read most of related questions in SO. I am seeking advise if below implemented solution is the right approach/method.

我已经阅读了许多有关如何在jersey-based Web应用程序中实现DI的教程,其中大多数教程建议必须在WEB-INF/*中创建beans.xml才能启用CDI,但是,我想知道是否使用Jersey的AbstractBinder是否达到相同的结果?

I have read many tutorials on how to implement DI in a jersey-based webapp and most of them recommend that its a must to create a beans.xml in WEB-INF/* in order to enable CDI but, I wonder if using Jersey's AbstractBinder achieve the same result?

我有一个jersey-webapp,在web.xml

I have a jersey-webapp that has the following in web.xml

    <servlet>
    <servlet-name>Test Jersey</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.test.config.AppConfig</param-value>
    </init-param>

com.test.config.AppConfig如下

public class AppConfig extends ResourceConfig {
    public AppConfig() {
        AbstractBinder binder = new AbstractBinder() {
            @Override
            protected void configure() {                    
              bind(Impl.class).to(Interface.class).in(Singleton.class);
            }
        };
        register(binder);
        register(MultiPartFeature.class);
        packages("..."); //packages
    }
}

然后我注释接口并注入实现

and then I annotate the interfaces and the implementation gets injected

@Inject 
private SomeInterface someInterface; 

以上工作正常.无论我要注入什么,我都将其包含在binder中,然后指定一个injection point,它将被注入.

Above works just fine. Whatever that I want to be injected, I include it in the binder and then specify an injection point and it gets injected.

WEB-INF/目录中没有beans.xml,我想知道是否在扩展ResourceConfigAppConfig中使用AbstractBinder消除了声明beans.xml的需要?

There is no beans.xml in WEB-INF/ directory and I wonder if using AbstractBinder inside AppConfig that extends ResourceConfig eliminate the need to declare beans.xml ?

添加beans.xml可能会启用对类的扫描,这将在我们用@Component@ManagedBean注释类时为DI铺平道路.

Adding beans.xml would probably enable scanning of classes that would pave the way for DI when we annotate classes with @Component or @ManagedBean.

无论如何,我很高兴听到您对是否应该提供反馈/建议/建议/建议

Regardless, I would be happy to hear your feedback/advise/suggestions/recommendations on whether to

  1. 坚持使用现有解决方案(如上所示)在泽西岛的DI,因为....?
  2. 切换到注释类(需要注入),并使用beans.xml的注释发现,因为...?
  3. Jersey默认使用HK2,是否值得使用其他DI 集装箱还是HK2够好?
  4. 与JavaEE 6相比,您对Jersey的Spring DI的看法如何? CDI仅用于DI用途?
  1. Stick with existing solution (shown above) for DI in Jersey because .... ?
  2. Switch to annotating classes (that needs to be injected) and use annotation-discovery of beans.xml because ... ?
  3. Jersey uses HK2 by default, is it worth using a different DI container or HK2 is good enough?
  4. What is your view on Jersey's Spring DI in comparison with JavaEE 6 CDI only for DI purposes?

有许多教程说明Tomcat不支持CDI吗?但在使用AbstractBinder的情况下工作了,我猜它是因为我以编程方式绑定了吗?有任何评论.

There are many tutorials stating that CDI is not supported by Tomcat? but worked above using AbstractBinder and I guess its because I programmatically bind? Any comments.

推荐答案

我没有明确的答案,可能没有正确的答案.尤其重要,因为在版本2.15中引入了 Weld SE支持",这当然不是没有任何原因的.但我想尝试一下:

I do not have a clear answers and possibly there doesn't exist a correct one. Not least because Weld SE support was introduced in version 2.15 of Jersey and this certainly not without any reason. But I would like to give it a try:

  1. 所示的解决方案对于非复杂的项目结构很好,但是声明每个单独的绑定可能不是最佳解决方案
  2. 您不需要使用beans.xml.注释和自动绑定需要付出额外的努力才能正常工作(请参见下文)
  3. 我对此不确定,但会说Weld似乎更先进.当然,您可以将CDI混合使用.
  4. (此处无答案)
  1. The shown solution works fine for non-complex project structures but declaring every single binding might not be the best solution
  2. You don't need to use beans.xml. Annotations and auto-binding works fine with some additional effort (see below)
  3. I'm not sure about this, but would say Weld seems to be more advanced. And of course you could mix CDI with some effort.
  4. (no answer here)

以下是示例,我认为这可能很有趣:

Here the example, which I think could be interesting:

依赖关系(Maven):

Dependencies (Maven):

<dependency>
  <groupId>org.glassfish.hk2</groupId>
  <artifactId>hk2-metadata-generator</artifactId>
  <version>2.5.0-b05</version> <!-- HK2 version int. used by Jersey 2.23.2  -->
</dependency>
<dependency>
  <groupId>org.glassfish.jersey.containers</groupId>
  <artifactId>jersey-container-servlet</artifactId>
</dependency>

应用程序事件侦听器:

An application event listener:

import org.glassfish.hk2.api.*;
import org.glassfish.jersey.server.*;

@Provider
public class ApplicationListener implements ApplicationEventListener {

    @Inject ServiceLocator serviceLocator;

    @Override
    public void onEvent(ApplicationEvent event) {
        switch (event.getType()) {
        case INITIALIZATION_FINISHED:
            onInitFinished();
            break;
        case DESTROY_FINISHED:
        case INITIALIZATION_APP_FINISHED:
        case INITIALIZATION_START:
        case RELOAD_FINISHED:
        default:
            break;
        }
    }

    @Override
    public RequestEventListener onRequest(RequestEvent requestEvent) { return null; }

    public void onInitFinished() {
        populate(serviceLocator);
    }

    private void populate(ServiceLocator serviceLocator) {
        DynamicConfigurationService dcs = serviceLocator.getService(DynamicConfigurationService.class);
        Populator populator = dcs.getPopulator();
        try {
            populator.populate();
        } catch (IOException | MultiException e) {
            throw new MultiException(e);
        }
    }
}

合同:

import org.jvnet.hk2.annotations.Contract;

@Contract
public interface ExampleService {
    void executeSomething();
}

一项或多项服务:

import javax.inject.Named;
import org.jvnet.hk2.annotations.Service;

@Service
@Named("bar")
public class BarService implements ExampleService {

    @Override
    public void executeSomething() { /* doBar */ }

}

用法:

@Path("/")
public class TestResource {

    // either ...
    @Inject
    @Named("bar")
    private ExampleService bar;

    // or ...
    @Inject
    private IterableProvider<ExampleService> services;

}

只是摆脱beans.xml(我从未使用过或从未见过的)或在ResourceConfig中声明的选项,但它可能会找到感兴趣的人:)

Just an option to get rid of beans.xml (which I've never used or have seen) or declaration within ResourceConfig, but it might find interested parties :)

此外,似乎 Jersey 3.0 即将来临^^

Additionally, it seems like Jersey 3.0 is comming ^^

祝您有美好的一天!

这篇关于使用带有或不带有抽象绑定的Jersey的CDI进行依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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