0

我正在尝试修改我们现有的创建自己的代理 bean 的 CDI 扩展。现在只为每个服务创建了一个代理。服务具有类似于应用程序范围的内容,因此始终只有一个服务实例。

我想要完成的是为每个注入点创建一个代理 bean。我需要它们来存储一些特定于给定注入点的信息。如果同一个服务有更多的注入点,就会有更多的代理 bean,但它们后面仍然有一个服务实例。但是,当我以这种方式更改行为时,Weld 抱怨依赖关系不明确,因为它无法在两个完全相同的代理之间进行选择。

我怎样才能解决这个问题?基本上,我所做的是观察ProcessBean事件并为每个发现的 bean 的每个注入点创建一个新代理。然后我使用AfterBeanDiscovery#addBean方法将所有这些代理 bean 添加到容器中。我会以某种方式需要跳过最后一步并将它们手动注入到它们的注入点,或者能够影响选择要注入的正确 bean 的决定。如果给我一个注入点和一个可以注入其中的模棱两可的依赖项列表,我将能够根据其属性选择正确的依赖项。但我真的不知道是否有可能为 Weld 做出这个决定,以及我该怎么做。

编辑:我想做的只是实现我自己的范围,类似于@Dependent但使用代理,我可以在其中存储一些与给定注入点相关的附加信息。

EDIT2:我终于通过创建一个新的限定符来修复它,该限定符携带有关特定注入点的信息。这个限定符被添加到注入点和它的代理中。但这不是很好的解决方案,因为我必须用我自己的实现替换注入点,这允许修改限定符集合。我觉得必须有一个更优雅的解决方案。请让我知道如果你能想到任何。

4

1 回答 1

0

Firstly to your solution with qualifiers - it is indeed correct approach, however in the given situation a tad bit redundant work I guess.

If I get your case correctly, you could use two observers in a single extension.

First one would observe ProcessBeanAttributes phase and veto() the original bean which you don't want.

void observePBA(@Observes ProcessBeanAttributes<?> bean) {
  // I used '?' as a type, so here you do your check for 
  // the actual bean class to know which one is it and whether
  // you actually want to veto such bean
  bean.veto();
}

The other observer is what you have already - adding your own bean in AfterBeanDiscovery#addBean.

void observeABD(@Observes AfterBeanDiscovery abd) {
  // add your custom bean, assuming you have it prepared somewhere
  abd.addBean(myCustomBean);
}

This way, as the container boots up, you will remove the original beans and add your custom one. That way, Weld should have no ambiguous resolution problems.

于 2016-11-21T14:17:16.790 回答