如何在没有代理重新创建的情况下更改CDI(Weld)代理下的实例(目标)

问题描述 投票:-1回答:1

如果某些属性发生更改,我想刷新bean(destroy,initialize),例如db url connection。问题是这个bean可能已经注入了CDI容器中的其他bean。我有两个想法:1。如果bean被代理 - 销毁此代理的目标,重新初始化此代理中的目标。 2.对于@Singleton@Dependent bean,因为它们没有代理,我可以将这些bean包装在代理中并按上述方式执行。我想在代理中包装它的原因是当属性改变并且我想重新创建真实对象时,我还应该知道所有依赖于我的bean的依赖bean。所以我的问题是:1。如何在CDI中替换代理中的真实对象?或者2.如果我不想保留代理,如上所述,如何为我的bean创建代理对象并将其重新注入CDI容器中的所有依赖bean?

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

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

java dependency-injection proxy cdi weld
1个回答
0
投票

对于@DependedSCoped bean,您可以使用类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在使用后没有正确丢弃。

© www.soinside.com 2019 - 2024. All rights reserved.