繁体   English   中英

在 CDI 中生成可选 Bean

[英]Produce Optional Beans in CDI

我想在方法上使用@Produces注释创建一个 CDI 工厂,以便在外部服务中查找命名的东西,并返回(生成)外部服务中的代理以注入到其他 bean 中。 从用例的角度来看,通常需要所有这些依赖项; 但是有时会发生远程服务中不存在请求的内容,应用程序可以对此做出反应。

基本上结构是这样的:

@Singleton public class SomeBean {
  @Inject @MyName("required") private Something requiredSomething;
  @Inject @MyName("optional") private Instance<Something> optionalSomething;

  @PostConstruct void init() {
    if (optionalSomething.isUnSatisfied()) {
      // act without optional Something in external service
    } else {
      optionalSomething.get().doWhatIWant(NOW);
    }
  }
}

@ApplicationScoped
public class SomethingFactory {
  @Inject private RemoteSomethingService remoteService;

  @Produces
  @MyName(value = "")
  public Something createRemoteSomething(InjectionPoint injectionPoint) {
    MyName name = injectionPoint.getAnnotated().getAnnotation(MyName.class);
    Something some = remoteService.lookup(name.value()); // throws an exception if lookup fails
    return some;
  }
}

这适用于需要使用某些东西的一侧的注入:成功的查找注入查找的Something实例,而不成功的查找会破坏 bean 引导。 然而,在一个不存在的东西的可选注入的情况下,它要么中断,因为Instance.isUnSatisfied()返回false 如果我让createRemoteSomething()抛出异常,则在调用optionalSomething.get()期间会引发此异常; 如果我改为返回null ,则相同的调用会导致 NPE。

如何使用 CDI 原语实现这一点? 谢谢。

您的生产者方法很好(我假设它的返回类型应该是Something )。 您正在@Dependent范围(默认)中生成一个Something

@Dependent范围内的内容可能为null 一般来说没有别的可能。 (CDI 中有一些从古代开始的剩余部分,当时其他范围可以产生null对象,但它们是过去时代的残余。)

所以在你的情况下,当你不能产生你想要的东西时,只需从你的生产者方法返回null ,但这不是一个错误条件(否则显然会抛出某种异常)。

然后,在消费方面,您几乎就在那里。

Instance#isUnsatisfied()仅在没有生产者方法(或其他类型的 bean)可以“制作”所要求的东西时才返回true 在你的情况下,可以“制造”的东西被要求制片方式,所以isUnsatisfied()返回false ,那就是正确的。

你所要做的就是改变这个:

optionalSomething.get().doWhatIWant(NOW);

…到:

final Something something = optionalSomething.get();
if (something == null) {
  // no such Something, but an expected case
} else {
  something.doWhatIWant(NOW);
}

同样,这仅适用于@Dependent范围内的Something (而不是@ApplicationScoped范围内的情况),而在您的情况下确实如此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM