2014-12-18 3 views
0

В приложении на моем Джерси я бы хотел, чтобы экземпляр ContainerRequestContext вводился в различные объекты. В случае, если объект, созданный вне контекста запроса, я хотел бы ввести null.Необязательно впрыскивать ContainerRequestContext

Я заметил, что 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. 

Было бы массово упростить мой код, если бы Джерси просто вводил нулевое значение, когда он находился за пределами области запроса, любые идеи, как это сделать?

ответ

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

Простой способ справиться с дополнительным впрыском является @Inject в javax.enterprise.inject.Instance<T>, и затем позвоните по телефону instance.isUnsatisfied() до instance.get().

Смежные вопросы