使用带有或不带有抽象绑定的Jersey的CDI进行依赖注入 [英] Dependency Injection using CDI with Jersey with/without abstract binding
问题描述
首先,这不是自以为是的问题,我已经阅读了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
,我想知道是否在扩展ResourceConfig
的AppConfig
中使用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
- 坚持使用现有解决方案(如上所示)在泽西岛的DI,因为....?
- 切换到注释类(需要注入),并使用
beans.xml
的注释发现,因为...? - Jersey默认使用
HK2
,是否值得使用其他DI 集装箱还是HK2够好? - 与JavaEE 6相比,您对Jersey的Spring DI的看法如何? CDI仅用于DI用途?
- Stick with existing solution (shown above) for DI in Jersey because .... ?
- Switch to annotating classes (that needs to be injected) and use annotation-discovery of
beans.xml
because ... ? - Jersey uses
HK2
by default, is it worth using a different DI container or HK2 is good enough? - 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:
- 所示的解决方案对于非复杂的项目结构很好,但是声明每个单独的绑定可能不是最佳解决方案
- 您不需要使用
beans.xml
.注释和自动绑定需要付出额外的努力才能正常工作(请参见下文) - 我对此不确定,但会说Weld似乎更先进.当然,您可以将CDI混合使用.
- (此处无答案)
- The shown solution works fine for non-complex project structures but declaring every single binding might not be the best solution
- You don't need to use
beans.xml
. Annotations and auto-binding works fine with some additional effort (see below) - 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.
- (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屋!