Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject a @RequestScoped bean twice as different instances

I have the following situation (Java EE, CDI, jax.rs):

I have a RequestScoped Bean, which stores some data used in the live time of a request:

MyHandler.java:
@RequestScoped
public class MyHandler
{
    ....
}

Then I have my REST call, which uses two different instances of my Handler Bean:

MyRestCall.java:
@Stateless
public class MyRestCall
{
    @Inject
    MyHandler handlerA;

    @Inject
    MyHandler handlerB;

    ....
}

However, what happens is, that hanlderA and handlerB is the same object. But I would like to have two different ones. How can I achieve that in a proper way? Of course, I could create a base class Handler and then derive two separate classes HandlerA and HandlerB and @Inject them as handlerA and handlerB. But I hope for a cleaner way.

like image 747
badera Avatar asked Dec 17 '25 20:12

badera


2 Answers

This bean is request scope so there should be exactly and only one such a bean served through all processing during request lifecycle. You should not expect to get a new one.

The scope that have such a behaviour is a @Dependent scope. Have you thought about using it for that bean? It will produce new bean every time you do inject of it so it look like a better solution for that. Of course in other places that you are using the same bean there will be the new one injected.

like image 178
Marek Smigielski Avatar answered Dec 20 '25 10:12

Marek Smigielski


Try using Instance annotate with @New:

@Inject
@New(MyHandler.class)
Instance<MyHandler> handlerInstanceA;

@Inject
@New(MyHandler.class)
Instance<MyHandler> handlerInstanceB;

And then get your instances using:

MyHandler handlerA = handlerInstanceA.get();
MyHandler handlerB = handlerInstanceB.get();

Update

The documentation says that @New was deprecated in CDI 1.1 and the @Dependent scope should be used instead:

The New qualifier was deprecated in CDI 1.1. CDI applications are encouraged to inject Dependent scoped beans instead.

So use:

@Inject
MyHandler handlerA;

@Inject
MyHandler handlerB;

Since @Dependent is the default CDI scope, leave your MyHandler without annotations or annotate it with @Dependent:

@Dependent
public class MyHandler {...}

According to the @Dependent documentation:

Beans declared with scope @Dependent behave differently to beans with other built-in scope types. When a bean is declared to have scope @Dependent:

• No injected instance of the bean is ever shared between multiple injection points.
• Any instance of the bean injected into an object that is being created by the container is bound to the lifecycle of the newly created object.

like image 33
cassiomolin Avatar answered Dec 20 '25 08:12

cassiomolin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!