问题描述
我发现如何使用Jersey(测试框架)将数据源依赖项注入到RESTful Web服务中?我想我会问一个不同的问题.
I found How can I inject a data source dependency into a RESTful web service with Jersey (Test Framework)? but I think I'm gonna ask a little bit different question.
我编写了一个JAX-RS库,并尝试使用 Jersey测试框架.
I wrote a JAX-RS library and I'm trying to unit-test with Jersey Test Framework.
我似乎HK2注射正确.但是我发现一些用@PostConstruct
或@PreDestroy
注释的生命周期拦截器方法没有被调用(或仅被某些调用).
I seems HK2 injects properly. But I found some of my life cycle interceptor method annotated with @PostConstruct
or @PreDestroy
aren't invoked (or only some invoked).
public class MyResource {
@PostConstruct
private void constructed() { // not invoked
}
@Inject
private Some some; // injection works.
}
如何使用Jersey测试框架启用CDI?我必须依靠哪种工件?
How can I enable CDI with Jersey Test Framework? What kind of artifacts do I have to depend on?
这是我当前的依赖关系.
Here is my current dependencies.
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<scope>test</scope>
</dependency>
推荐答案
我找到了解决方案.
我添加了以下其他依赖项.
I added following additional dependencies.
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-cdi1x</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-weld2-se</artifactId>
<scope>test</scope>
</dependency>
我认为现在Weld接管了HK2.我不知道jersey-cdi1x-ban-custom-hk2-binding
是干什么的.无论如何,我可以使用javax.enterprise:cdi-api
中的标准注释.
Now Weld takes over HK2, I think. I don't know what jersey-cdi1x-ban-custom-hk2-binding
is for. Anyway, I can use standard annotations from javax.enterprise:cdi-api
.
public class MyProducer {
@Produces @Some
public MyType produceSome() {}
public void disposeSome(@Disposes @Some MyType instance) {}
}
并添加了Weld的初始化代码.
And an initialisation code for Weld added.
@Override
protected Application configure() {
// this method works somewhat weirdly.
// local variables including logger
// is null in here
// I have to start (and join) a thread
// which initializes Weld and adds a shutdown hook
final Thread thread = new Thread(() -> {
final Weld weld = new Weld();
weld.initialize();
Runtime.getRuntime().addShutdownHook(
new Thread(() -> weld.shutdown()));
});
thread.start();
try {
thread.join();
} catch (final InterruptedException ie) {
throw new RuntimeException(ie);
}
final ResourceConfig resourceConfig
= new ResourceConfig(MyResource.class);
resourceConfig.register(MyProducer.class);
return resourceConfig;
}
注入每个点,并调用所有生命周期方法.是的!
Every points get injected and all lifecycle methods are invoked. Yay!!!
我不明白为什么我一开始尝试使用线程.
I don't understand why I tried to use a thread in the first place.
@Override
protected Application configure() {
final Weld weld = new Weld();
weld.initialize();
Runtime.getRuntime().addShutdownHook(new Thread(() -> weld.shutdown()));
final ResourceConfig resourceConfig
= new ResourceConfig(MyResource.class);
resourceConfig.register(MyProducer.class);
return resourceConfig;
}
自从我使用JerseyTestNg.ContainerPerClassTest
以来,我至少在TestNG上无法使用@BeforeClass
和@AfterClass
,因为configure()
方法是从构造函数中调用的(间接).
Since I use JerseyTestNg.ContainerPerClassTest
I failed, at least with TestNG, to work with @BeforeClass
and @AfterClass
because configure()
method is invoked (indirectly) from the constructor.
如果我切换到JerseyTestNg.ContainerPerMethodTest
,我想可以使用@BeforeMethod
和@AfterMethod
进行初始化/关闭焊接.
I think I can use @BeforeMethod
and @AfterMethod
for initializing/shutting-down Weld if I switch to JerseyTestNg.ContainerPerMethodTest
.
jersey-cdi1x
是jersey-weld2-se
的传递依赖项,因此可以省略.
jersey-cdi1x
is a transitive dependency of the jersey-weld2-se
so it can be omitted.
这篇关于如何使用Jersey测试框架启用CDI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!