【发布时间】:2020-02-26 07:59:13
【问题描述】:
我有基于 CDI 的应用程序。在运行时,我的应用程序会生成导致 bean 重新加载的自定义事件。 Bean 重新加载意味着遍历所有 bean 并重新初始化已经注入的 bean。重新初始化应该知道 bean 的依赖关系。例如:
class BeanA {
String url;
@PostConstruct
void init(){
url = UrlFactory.getNewUrl()
}
}
class BeanB {
@Inject
BeanA beanA;
@PostConstruct
void init(){
url = beanA.getUrl();
doSomethingWith(url);
}
因此,当事件发生时,BeanA 和 BeanB 应该按照严格的顺序重新初始化,因此在 BeanB 重新初始化期间,BeanB 已经知道在 BeanA 中初始化的新 url。 是否可以在运行时使用 CDI 中现有的工具(类似于 Spring:AutowireCapableBeanFactory)? 我发现 EJB 已经有 @DependsOn 注释,它能够在应用程序启动期间构建 bean 顺序。
我想出的最强力的解决方案是在应用程序启动期间监听 CDI 事件之一,收集所有 bean 并构建依赖关系图,并在重新加载期间通过此图并重新初始化。恐怕我不知道我可能会遇到很多陷阱(比如循环依赖、延迟初始化(在这种情况下它可能根本不起作用)以及我不知道的许多其他陷阱,因为没有漂亮很好地理解 CDI 容器在内部是如何工作的)
还有其他现有的技术可以真正解决我的问题吗?
【问题讨论】:
-
尝试使用
Provider<T>或Instance<T>:更多详情here -
需要注意的是 CDI Inject 代理,它不会注入实际实例。当调用代理上的方法时,CDI 代理会将您路由到正确的 bean 实例。