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

时间:2019-03-24 15:00:49

标签: java dependency-injection proxy cdi weld

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

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

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

1 个答案:

答案 0 :(得分:0)

对于@DependedSCoped豆,可以使用     类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范围的Bean,则必须知道注入目标获取了该Bean专用的实例,那么谁在更改值? @Dependend范围是否适合您的用例?

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

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

结论

随着用例变得清晰(请参阅下面的评论),它导致了实现自定义范围的意图,因为CDI似乎没有为该用例提供合适的范围。我建议尝试在可能的情况下找到提供的CDI范围,并仅在必要时实施自定义范围,因为您将必须注意bean的生命周期,范围的管理以及如何由范围管理的bean并将由应用程序使用。如果不谨慎实施,则自定义范围可能会导致诸如内存泄漏之类的问题,例如,如果在使用后未正确丢弃您的bean。