0

在我的 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 ,它将大大简化我的代码,有什么想法可以做到这一点吗?

4

2 回答 2

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;
    }

}
于 2014-12-19T11:01:46.947 回答
1

处理可选注入的简单方法是 to @Injectinto javax.enterprise.inject.Instance<T>,然后调用instance.isUnsatisfied()before instance.get()

于 2015-08-18T11:26:10.137 回答