使用带有/不带抽象绑定的Jersey的CDI依赖注入

时间:2016-08-17 18:31:43

标签: java tomcat dependency-injection jersey cdi

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

我已经阅读了许多有关如何在jersey-based网络应用中实施DI的教程,其中大多数建议必须在beans.xml中创建WEB-INF/*才能启用CDI但,我想知道使用泽西岛的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
    }
}

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

@Inject 
private SomeInterface someInterface; 

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

beans.xml目录中没有WEB-INF/,我想知道在AbstractBinder内使用AppConfig扩展ResourceConfig是否无需声明beans.xml }?

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

无论如何,我很乐意听取您对是否

的反馈/建议/建议/建议
  1. 坚持在泽西岛进行DI的现有解决方案(如上所示),因为......?
  2. 切换到注释类(需要注入)并使用beans.xml的注释发现,因为......?
  3. 泽西岛默认使用HK2,是否值得使用不同的DI 容器还是HK2还不够好?
  4. 与JavaEE 6相比,您对Jersey的Spring DI有什么看法? CDI仅用于DI目的吗?
  5. 有许多教程声明Tomcat不支持CDI?但是上面使用AbstractBinder工作,我猜它是因为我以编程方式绑定?任何评论。

1 个答案:

答案 0 :(得分:1)

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

  1. 显示的解决方案适用于非复杂的项目结构,但声明每个单独的绑定可能不是最佳解决方案
  2. 您无需使用beans.xml。注释和自动绑定可以通过一些额外的工作来完成(见下文)
  3. 我不确定这一点,但会说Weld似乎更先进。当然,你可以将CDI与一些努力结合起来。
  4. (这里没有答案)
  5. 这个例子,我认为可能很有趣:

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

    合同:

    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正在进行^^

    祝你有愉快的一天!