user2918640
user2918640

Reputation: 473

In CDI, how to give scope to a bean at the point of injection?

In CDI, I am able to inject a bean with a particular scope, the scope with which the bean class was defined. But what if I create the bean class without any scope and I give scope to that bean at the point of injection. My requirement is to make injection-time-scoping possible in the latter case. Problem is that injection is happening with dependent scope instead of the desired annotated scope unless I use a producer.

For Example:

CASE 1:

When I declare scope of a bean in its class declaration like this:

@ApplicationScoped
class UserDetails {
...
}

And injected like this:

@ViewScoped
class UserView {

    @Inject
    UserDetails userDetails;
    .
    .
}

It works as expected. The bean injected in application scope is available throughout the application in all other beans.


CASE 2:

But when I give no scope in class declaration:

class UserDetails {
...
}

And injected like this (giving scope at the point of injection):

@ViewScoped
class UserView {

    @Inject @ApplicationScoped
    UserDetails userDetails;
    .
    .
}

This failed!.. The injected bean did not inject in application scope but got dependent scope instead (View Scope in my case).

I had to create a Producer & a Qualifier where @Produces method is providing the bean in desired application scope. I feel this producer/qualifier extension turns out to be an overhead if I have to inject bean class UserDetails in application scope in this case.

Thing is, UserDetails class is part of a third party jar. This class does not have any scope declared and is a POJO. I can not change its source code.

Based on the above discussion, I have two questions:

  1. Why someone would create bean classes defined with no scope when they know that the beans are to be injected under a particular scope? Would this practice do any good in terms of design?

  2. As I do not have control over the source code of the bean classes and as they are not associated with any scope, Is producer/qualifier extension the only good way to inject such beans in the desired scope?

Upvotes: 3

Views: 2819

Answers (3)

LHA
LHA

Reputation: 9655

1. Object without scope defined - @Dependent used

CDI will treat Object wihout scope as @Dependent scope.

An instance of a dependent bean is never shared between different clients or different injection points. It is strictly a dependent object of some other object. It is instantiated when the object it belongs to is created, and destroyed when the object it belongs to is destroyed.

Beans with scope @Dependent don’t need a proxy object. The client holds a direct reference to its instance.

Spring IoC dev: CDI @Dependent scope is similar to Spring IoC Prototype scope.

2. No @Produces & just use @Inject

CDI will create new instance of UserDetails for each injection (@Dependent scope). No sharing data here! You can't define scope as you did (when inject).

3. Use @Produces & use @Inject

You can control the scope of UserDetails object (ApplicationScoped, SessionScoped, or RequestScoped)

public class Producers {

     @Produces @ApplicationScoped
     public UserDetails createUserDetails() {
         // Initialize UserDetails
     }

     public void release(@Disposes UserDetails userDetails) {
         // Release userDetails if you have to
     }
}

4. Another way: Extend UserDetails if possible

    @ApplicationScoped // Or @SessionScoped, @RequestScoped
    public class UserDetailsImpl extends UserDetails {
        //
    } 

If you want ApplicationScoped for UserDetails. Way 3 or way 4 can be used.

Upvotes: 6

Antonio Alliegro
Antonio Alliegro

Reputation: 1

I think you can inject an @ApplicationScoped bean as a @Dependent bean by specifying the @New annotation near the injection point, but you can't do the opposite.

Upvotes: 0

Harald Wellmann
Harald Wellmann

Reputation: 12865

The scope is always defined on the bean, not on the injection point.

An injection point cannot change the scope of the injected bean.

Upvotes: 2

Related Questions