java - 在 CDI 中生成可选 Bean
问题描述
我想@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
)。您正在生成范围Something
内@Dependent
(默认值)。
范围内的事情@Dependent
可能是null
. 一般来说,没有别的可能。(CDI 中有一些远古时代的剩余部分,其他示波器可以产生null
物体,但它们是过去时代的残余。)
所以在你的情况下,null
当你不能生产你想要的东西时,只需从你的生产者方法返回,但这不是错误条件(否则显然会抛出某种异常)。
然后,在消费方面,你就快到了。
Instance#isUnsatisfied()
true
仅当没有生产者方法(或其他类型的 bean)可以“制造”所要求的东西时才返回。在您的情况下,有一个生产者方法可以“制造”被要求的东西,所以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);
}
同样,这仅在您的情况确实如此的范围内(而不是范围内)Something
才@Dependent
有效。@ApplicationScoped
推荐阅读
- vb.net - 将 IQueryable 转换为另一种类型会引发错误“System.NotsupportedException”
- mongodb - Failover sharding mongodb. Autoreconnect doesnt work
- java - 如何直接从 CipherInputStream 加载解密文件而不存储它?
- c++ - 来自模板类的 C++ 访问类型名
- html - Testing using gtmetrix.com in YSLOW shows far-future expiration error
- javascript - Laravel, passed php variable to JS function showing as Key not Value
- java - 如何不逐行查找 BufferedReader 类对象是否包含特定单词?
- qt - QCommandLineOption: count repeated argument?
- java - 对给定集合对象执行迭代时迭代器的意外输出
- android - Unresolve Reference for MutableLiveData in Kotlin/IntelliJ?