如何在不重新创建代理的情况下更改 CDI(焊接)代理下的实例(目标)

How to change instance (target) under CDI (Weld) proxy without proxy recreation

如果某些 属性 发生更改,例如 db url 连接,我想刷新 bean(销毁、初始化)。问题是这个 bean 可能已经被注入到 CDI 容器中的其他 bean 中。我对此有两个想法: 1. 如果 bean 被代理 - 销毁此代理的目标,在此代理内重新初始化目标。 2. 对于 @Singleton@Dependent beans,因为它们没有被代理,所以我可以将这些 beans 包装在代理中并执行与上面相同的操作。 我想将其包装在代理中的原因是,当 属性 更改并且我想重新创建真实对象时,我还应该知道所有依赖于我的 bean 的依赖 bean。 所以我的问题是: 1、如何在CDI中替换proxy中的真实对象?要么 2. 如果我不想像上面解释的那样保留代理,如何为我的 bean 创建代理对象并将其重新注入到 CDI 容器中的所有依赖 bean?

这是我之前的问题: Re-inject CDI bean if some injected property changed

同样,我使用 CDI(焊接),而不是 Spring IoC,所以我不能使用 Spring 云配置中的 @RefreshScope,但我认为我的预期功能可能类似使用自定义范围。

对于@DependedSCoped bean,你可以使用 class MyBean {

   @Inject
   private Instance<MYType> myTypeInst;

   // This will ensure, that the bean is always fresh created.
   // But the property value on the former instance will be lost
   // So the changable value has to be provided another way to the created bean
   public void do SomeThing(){
      MyType bean = myTypeInst.get();

      myTypeInst.destroy(bean);
   }
}

如果您使用@Depended scoped bean,那么您必须知道注入目标获取其专用于该bean 的实例,那么谁在更改该值? @Dependend 范围是否适合您的用例?

不需要提供自己的代理或入侵现有代理,只需为您的用例找到合适的范围并正确实现 bean 即可。如果连接 url 可以更改,那么管理连接的 bean 必须知道更改并重新创建连接,并且使用此 bean 的 bean 需要在每次使用时检索连接。

也许您可以提供您的用例描述,然后我们也许可以为您提供更好的答案。

结论

随着用例变得清晰(见下面的评论),它导致了实现自定义范围的意图,因为 CDI 似乎没有为这个用例提供合适的范围。我建议尽可能尝试找到提供的 CDI 作用域,并仅在必要时实现自定义作用域,因为您将不得不关心 bean 的生命周期、作用域的管理以及由作用域管理的 bean 如何能够并将被应用程序使用。如果不小心实现自定义范围可能会导致内存泄漏等问题,例如,如果您的 bean 在使用后未正确丢弃。