在我的Jersey应用程序中,我希望将ContainerRequestContext
实例注入到各种对象中。如果在请求的上下文之外创建对象,我希望null被注入。
我注意到HK2有一个@Optional
注释,您可以用它来注释依赖项,我希望能够完成这项工作,不幸的是它根本不会改变行为。
public class MyObject {
private final ContainerRequestContext containerRequestContext;
@Inject
public MyObject(@Optional ContainerRequestContext containerRequestContext) {
this.containerRequestContext = containerRequestContext;
}
}
如果在请求范围之外实例化此对象(在我的情况下,由Quartz调度程序运行作业),则会抛出类似这样的异常:
java.lang.IllegalStateException: Not inside a request scope.
如果Jersey在请求范围之外只注入null,它会大规模简化我的代码,任何想法如何做到这一点?
答案 0 :(得分:1)
我已经找到了一种方法,但它基本上是一种黑客攻击。您可以尝试从ContainerRequestContext
显式获取ContainerRequestContext
实例,而不是注入ServiceLocator
,并在上下文位于请求范围之外时处理异常。
public class MyObject {
private final Optional<ContainerRequestContext> containerRequestContext;
@Inject
public MyObject(ServiceLocator serviceLocator) {
this.containerRequestContext = getContainerRequestContext(serviceLocator);
}
private Optional<ContainerRequestContext> getContainerRequestContext(ServiceLocator serviceLocator) {
try {
return Optional.of(serviceLocator.getService(ContainerRequestContext.class));
} catch (MultiException e) {
if (e.getCause() instanceof IllegalStateException) {
return Optional.empty();
} else {
throw new ExceptionInInitializerError(e);
}
}
}
}
然后可以更进一步,创建自己的OptionalContainerRequestContext
类型。
public class OptionalContainerRequestContext {
private final Optional<ContainerRequestContext> containerRequestContext;
@Inject
public OptionalContainerRequestContext(ServiceLocator serviceLocator) {
this.containerRequestContext = getContainerRequestContext(serviceLocator);
}
public ContainerRequestContext get() {
return containerRequestContext.get();
}
public boolean isPresent() {
return containerRequestContext.isPresent();
}
private Optional<ContainerRequestContext> getContainerRequestContext(ServiceLocator serviceLocator) {
try {
return Optional.of(serviceLocator.getService(ContainerRequestContext.class));
} catch (MultiException e) {
if (e.getCause() instanceof IllegalStateException) {
return Optional.empty();
} else {
throw new ExceptionInInitializerError(e);
}
}
}
}
然后你可以绑定它:
bind(OptionalContainerRequestContext.class).to(OptionalContainerRequestContext.class);
然后将其注入您需要的任何地方:
public class MyObject {
private final OptionalContainerRequestContext optionalContainerRequestContext;
@Inject
public MyObject(OptionalContainerRequestContext optionalContainerRequestContext) {
this.optionalContainerRequestContext = optionalContainerRequestContext;
}
}
答案 1 :(得分:1)
处理可选注入的简单方法是@Inject
进入javax.enterprise.inject.Instance<T>
,然后在instance.isUnsatisfied()
之前调用instance.get()
。