【问题标题】:CDI context reload in runtime在运行时重新加载 CDI 上下文
【发布时间】: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 实例。

标签: java ejb cdi java-ee-8


【解决方案1】:

首先,创建一个生产者方法,@Produces 你的String-typed url 值(可能创建一个@URL 限定符注释以进一步识别它)。在@Dependent 范围内生成它。比如:

@Produces @Dependent @URL private static final String produceUrl() {
  return UrlFactory.getNewUrl();
}

现在任何人在任何地方执行@Inject @URL private String url,他们都会从您的UrlFactory 获得一个新的String 表示网址。

更重要的是,只要有人执行@Inject @URL private Provider<String> urlProvider;,他们都会得到一个Provider,其get() 方法在调用时将返回最新和最大的URL 值。

如果你没看错的话,这可能就是你所需要的。

如果这不是你所需要的,那么让BeanA 这样做:

@Inject
@URL
private Provider<String> urlProvider;

...然后在其(上面省略)getUrl() 方法中,执行以下操作:

public String getUrl() {
  return this.urlProvider.get();
}

您每次都会收到一个新的String

如果您已完成,那么您只需将BeanA 添加到您的观察者方法中并将其交给您:

private static final void onEvent(@Observes final YourEvent event, final BeanA beanA) {
  final String url = beanA.getUrl(); // latest and greatest      
}

【讨论】:

  • 感谢莱尔德的回答。但是如果 UrlFactory 也在监听 YouEvent 并从这个事件中获取新的 url 怎么办?在这种情况下,当事件发生时,UrlFactory 应该获取新的 url,然后才能在依赖 bean 中使用。是否有可能以某种方式告诉:BeanA 依赖于 UrlFactory,BeanB 依赖于 UrlFactory 以允许 UrlFactory 在 BeanA 和 BeanB 重新初始化之前重新初始化它的状态?
猜你喜欢
  • 2019-07-26
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 2016-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
相关资源
最近更新 更多