当前位置: 首页 > 知识库问答 >
问题:

在CDI中生产可选的豆子

毋炳
2023-03-14

我想在一个方法上使用@products注释创建一个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的一侧的注入的情况:成功的查找注入已查找的Something实例,而不成功的查找破坏bean引导。然而,在使用不存在的东西进行可选注入的情况下,它要么因为实例而中断。isUnSatisfied()返回false。如果我退出抛出异常的createRemoteSomething(),则在调用optionalSomething时会引发此异常。get();如果我返回null,相同的调用将导致NPE。

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

共有1个答案

卢元龙
2023-03-14

您的生产者方法很好(我假设它的返回类型应该是某物)。您正在@依赖范围(默认值)中生成某物

@依赖的范围内的东西可能是null。一般来说,没有其他东西可能是。(CDI中有一些剩余的位,从古代其他范围可以产生null对象,但它们是过去时代的残余。)

因此,在您的情况下,当无法生成所需内容时,只需从producer方法返回null,但这不是错误条件(否则显然会引发某种异常)。

然后,在消费方面,你就快到了。

Instance#isunsatisfed()仅当没有生产者方法(或其他类型的bean)可以“生成”被请求的对象时,才会返回true。在您的例子中,有一个producer方法可以“生成”被请求的内容,因此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);
}

同样,只有当某物@依赖范围内(而不是,比如说,@Application ationScoped范围)时,这才有效,在您的情况下确实如此。

 类似资料:
  • 有人能解释一下CDI范围注释在生产者中的作用吗?他们似乎什么也做不了。 这些,自然地,在启动时给出了这个(省略的)错误。 WELD-001409:类型的依赖关系不明确。可能的依赖关系: 带有限定符[@Any@Default]的生产者方法[Thing]声明为[[BackedAnnotatedMethod]@生成公共pkg。测验东西制作人。thingMaker(), 因此,尽管“RequestScop

  • 我正在尝试实现一个基于运行时配置的Quarkus扩展,它提供了一个SecurityIdentityUggmentor。 部署: 我的处理器 运行时: 我的录音机: 在客户端应用程序中生成MyAugmentor实例的唯一方法是添加一个bean。扩展的运行时模块中的xml。但是我没有看到豆子。github repo中的其他扩展中的xml。有人能给我指一下正确的方向吗?

  • 使用野蝇8.2.0。最后,我相信使用焊接2.2,我已经在Maven多模块项目中用2个简单的类重现了这个问题。一个产生一个,另一个产生一个注入点。Arquillian部署失败与:不满足的依赖关系。生产者位于包含在消费者的WEB-INF/lib中的库jar中。生产者在META-INF中有一个,其中,消费者在WEB-INF中有一个。 复制步骤:下载此项目并从根目录运行。 这是一个关键错误。还有一些关于W

  • 在Spring DI中,将autowired字段声明为可选字段可以使客户端不向其注入任何值。使用Java EE的CDI是否可能做到这一点?我试过可选但失败了。我想知道是否有一个等价的机制我可以使用。 下面是我尝试的: 我得到一个错误消息:线程“main”org.jboss.weld.exceptions.deploymentexception:WELD-001408在注入点[[BackedAnno

  • 问题内容: 我有执行和将其结果转换为自定义数据模型类型数组的代码。抓取可能会抛出,但是我不想关心该错误,因此我使用,并且也在铸造中使用。在Swift 2中,这过去还不错,但是Swift 3产生了一个double可选: 如何改写可选绑定的右侧,以便其类型简单地成为数组?我认为在以下布尔条件(以前是子句)中,数组仍然是可选的,这看起来很荒谬。 问题答案: 您必须像这样将呼叫包装在括号内: 那是因为它的

  • 问题内容: 我一直在使用babel-node和带有babelify转换的browserify开发站点,以支持ES6语法。 我只是想知道,我是否可以在生产环境中运行它, 而不是 在节点中运行ES6还需要其他哪些选项? 这是我正在运行的用于构建和开始开发的命令 这是我的开发依赖 问题答案: 对于客户端代码 ,您正在做正确的事情。并将其运送给客户。 对于服务器端代码 ,我将使用babel- cli 进行