0

I am trying to modify our existing CDI extension which creates its own proxy beans. Now there is only a single proxy created for each service. Services have something like application scope so there is always only a single instance of a service.

What I want to accomplish is to create a single proxy bean for every injection point. I need them in order to store some information specific for the given injection point. If there are more injection points for the same service, there will be more proxy beans but still a single instance of a service behind them. However, when I change the behavior this way, Weld complains about ambiguous dependencies since it cannot choose between two exactly same proxies.

How can I fix this? Basically, what I do is observing ProcessBean event and creating a new proxy for each injection point of every single discovered bean. Then I am adding all those proxy beans to container using AfterBeanDiscovery#addBean method. I would somehow need to skip this last step and inject them manually to their injection points or be able to influence the decision of choosing the right bean to be injected. If I am given an injection point and a list of ambiguous dependencies which can be injected into it, I will be able to choose the right one based on its attribute. But I do not really know if it is possible to make this decision for Weld and how I can do it.

EDIT: Simply what I want to do is to implement my own scope similar to @Dependent but with proxies in which I can store some additional information related to given injection point.

EDIT2: I have finally fixed it by creating a new qualifier carrying information about specific injection point. This qualifier is added to both injection point and its proxy. But it is not very nice solution since I have to replace injection points with my own implementation which allows modification of qualifiers collection. I sense there must be a more elegant solution. Please, let me know if you can think of any.

livthomas
  • 1,160
  • 1
  • 14
  • 25

1 Answers1

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.

Siliarus
  • 6,393
  • 1
  • 14
  • 30
  • If I understand it correctly what you suggest is to veto the original beans. But this is not a problem in my case since they do not fit to any injection point and are only looked up manually by proxies when a method is called. The problem is when there are two injection points with the same type and qualifiers and two exactly the same proxies (only with different settings inside them) are created. – livthomas Nov 22 '16 at 19:29
  • Well then I might have misunderstood your text. Snippets of code might help. I thought that the candidates for injection are 1) the original bean, 2) your newly created proxy. – Siliarus Nov 23 '16 at 13:26
  • Actually, the project is open source so you can see it all. I made the changes described here in [this commit](https://github.com/SilverThings/SilverWare/commit/abb44eae805f78f8b88959bd740f9d31cfe042d8). – livthomas Nov 23 '16 at 19:40