Currently, I have everything working with one injection of my CDI bean, but I need about 6 to 10 separate instances(?) depending on my inputs. (Ideally, I would like to be able to inject a dynamic number of the same CDI beans depending on how many I need.)
Unfortunately, I need to have the beans injected since the class depends on another CDI bean. (See the 2.CDI bean class below)
@ApplicationScoped
public class Clients {
Publisher pub;
Subscriber sub;
@Inject
ListenerBean listener;
public void init(){
pub = new Publisher();
sub = new Subscriber(listener);
}
}
@Dependent
public class ListenerBean{
@Inject
private eventHandler h;
public void onMessage(Msg msg){
h.doesSomething();
}
}
The functionality I'm looking for, but not sure what's available out there. I haven't found anyone looking to accomplish the same thing.
for(Subscriber s: listOfSubscribers){
@Inject
ListenerBean l;
s = new Subscriber(l);
}
// The only thing I can do right now is
@Inject
ListenerBean listener1;
@Inject
ListenerBean listener2;
@Inject
ListenerBean listener3;
@Inject
ListenerBean listener4;
If you need to inject several different instances of a @Dependent
scoped bean, you could do it via programmatic lookup - in other words via Instance<T>
.
Every bean resolution for a @Dependent
bean via Instance
will result in a new bean instance created. Following code illustrates that:
@Inject Instance<ListenerBean> instance;
public void createMultipleBeanInstances() {
// bean1 and bean2 are two different instances because the bean is @Dependent
// you can OFC do this in a cycle and generate as many as you like
ListenerBean bean1 = instance.get();
ListenerBean bean2 = instance.get();
}
Just note that dependent beans you create via programmatic lookup have their lifecycle bound to the Instance
object meaning they will exist so long as does the Instance
. Given that you @Inject Instance
into the bean, it will be destroyed along with the bean it was injected into.
Explanation following my comment. I might be misunderstanding your question though.
First of all, your code looks basically like the implementation of a multicaster: you inject several objects which all implement a common interface to call the same method.
I think, that in trying to inject the various receiver objects, you basically have an XY-problem: does the emitter really need to know the receivers, or is it enough, that the event reaches the targets?
If I am right with the assumption, that your emitter does not really need to know the subscribers, you can simply use the Event
standard mechanism:
First, define a message (which can carry additional information, but this is not specifically necessary, you just need a class):
public class MyMessage {
// if needed, add some fields
}
Then, in your emitter, inject the corresponding event type, and use it to fire the message:
@Inject
private Event<MyMessage> myEvent; // note: type is message, not the bean
...
myEvent.fire(new MyMessage()); // to broadcast the message to everyone who is interested
In your subscribers, just @Observe the message:
public void theMethodWeWantCalled(@Observes MyMessage messageObject) {
// do things here
}
That's it: no need to couple emitter and subscriber.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.