首先,这不是自以为是的问题,我已经阅读了 SO 中的大部分相关问题。如果下面实现的解决方案是正确的方法/方法,我正在寻求建议。
我阅读了很多关于如何在 jersey-based
中实现 DI 的教程webapp,他们中的大多数人都建议必须创建一个 beans.xml
在 WEB-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.xml
在 WEB-INF/
目录,我想知道是否使用 AbstractBinder
里面AppConfig
延伸 ResourceConfig
无需申报 beans.xml
?
添加beans.xml
当我们用 @Component
注释类时,可能会启用扫描为 DI 铺平道路的类或 @ManagedBean
.
无论如何,我很乐意听到您的反馈/建议/建议/推荐
- 坚持使用 Jersey DI 的现有解决方案(如上所示),因为......?
- 切换到注释类(需要注入(inject))并使用
beans.xml
的注释发现因为……? - Jersey 使用
HK2
默认情况下,是否值得使用不同的 DI 容器或 HK2 是否足够好? - 与 JavaEE 6 相比,您对 Jersey 的 Spring DI 有何看法 CDI 仅用于 DI 目的?
有很多教程说Tomcat不支持CDI?但在上面使用 AbstractBinder
工作我猜是因为我以编程方式绑定(bind)?任何意见。
最佳答案
我没有明确的答案,可能也不存在正确的答案。尤其是因为 Weld SE support was introduced in version 2.15 of Jersey这当然不是没有任何理由的。但我想试一试:
- 所示解决方案适用于非复杂的项目结构,但声明每个绑定(bind)可能不是最佳解决方案
- 您不需要使用
beans.xml
。注释和自动绑定(bind)在一些额外的努力下工作正常(见下文) - 我对此不确定,但可以说 Weld 似乎更先进。当然,您可以付出一些努力来混合 CDI。
- (这里没有回答)
这是我认为可能很有趣的示例:
依赖关系(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/