java - 在有/没有抽象绑定(bind)的情况下使用 CDI 和 Jersey 的依赖注入(inject)

标签 java tomcat dependency-injection jersey cdi

首先,这不是自以为是的问题,我已经阅读了 SO 中的大部分相关问题。如果下面实现的解决方案是正确的方法/方法,我正在寻求建议。

我阅读了很多关于如何在 jersey-based 中实现 DI 的教程webapp,他们中的大多数人都建议必须创建一个 beans.xmlWEB-INF/*为了启用 CDI 但是,我想知道是否使用 Jersey 的 AbstractBinder达到同样的结果?

我有一个 jersey-webapp,它在 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
    }
}

然后我注释接口(interface)并注入(inject)实现

@Inject 
private SomeInterface someInterface; 

以上工作正常。无论我想注入(inject)什么,我都将其包含在 binder 中。然后指定 injection point它被注入(inject)。

没有beans.xmlWEB-INF/目录,我想知道是否使用 AbstractBinder里面AppConfig延伸 ResourceConfig无需申报 beans.xml

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

无论如何,我很乐意听到您的反馈/建议/建议/推荐

  1. 坚持使用 Jersey DI 的现有解决方案(如上所示),因为......?
  2. 切换到注释类(需要注入(inject))并使用 beans.xml 的注释发现因为……?
  3. Jersey 使用 HK2默认情况下,是否值得使用不同的 DI 容器或 HK2 是否足够好?
  4. 与 JavaEE 6 相比,您对 Jersey 的 Spring DI 有何看法 CDI 仅用于 DI 目的?

有很多教程说Tomcat不支持CDI?但在上面使用 AbstractBinder 工作我猜是因为我以编程方式绑定(bind)?任何意见。

最佳答案

我没有明确的答案,可能也不存在正确的答案。尤其是因为 Weld SE support was introduced in version 2.15 of Jersey这当然不是没有任何理由的。但我想试一试:

  1. 所示解决方案适用于非复杂的项目结构,但声明每个绑定(bind)可能不是最佳解决方案
  2. 您不需要使用beans.xml。注释和自动绑定(bind)在一些额外的努力下工作正常(见下文)
  3. 我对此不确定,但可以说 Weld 似乎更先进。当然,您可以付出一些努力来混合 CDI。
  4. (这里没有回答)

这是我认为可能很有趣的示例:

依赖关系(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>

应用程序事件监听器:

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);
        }
    }
}

契约(Contract):

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 中的声明的选项,但它可能会找到感兴趣的各方: )

此外,它看起来像 Jersey 3.0来了^^

祝你有美好的一天!

关于java - 在有/没有抽象绑定(bind)的情况下使用 CDI 和 Jersey 的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39003933/

相关文章:

facebook-graph-api - Java HTTP 获取对 facebook 的请求。错误的请求

dependency-injection - Ioc/DI - 为什么我必须引用应用程序入口点中的所有层/组件?

java - 如何在 spring 中配置 Autowiring

tomcat - 莺 - 没有这样的文件加载错误

java - 跨多个 <Host> 元素为公共(public)库共享单个类加载器是否安全?

c# - 如何将 IDictionary 属性与 Ninject 绑定(bind)?

java - Akka Config - application.conf - 设置调度程序和路由器

java - 在 Android 中将 vector 路径移动到固定位置

java - menuitem.getmenuinfo() 为动态创建的 View 返回 null

java - 哪些库可用于解析 IP header 字节的 Java?