Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CDI with unmanaged objects

Suppose that I have two classes, first a class without any properties, fields or annotations:

public class B {}

And a class which gets B injected, like this:

public class A {
    @Inject
    private B b;

    public B getB() {
        return b;
    }
}

Now class A is pretty useless until we use it, so there are two options:

  • @Inject it
  • Construct it manually, using the trusty "new A()"

If A gets injected, CDI manages it and is kind enough to inject B which has the implicit scope of @Dependent. Cool, just what I want.

However, if I manually construct A (let's say in a factory or a builder), CDI completely ignores my object and won't inject an object of type B.

Example I'm talking about when it doesn't work, here object a will always remain null:

public class Builder {
    @Inject
    private A a;

    public static Builder ofTypeSomething() {
        // do some magic here
        return new Builder();
    }

    private Builder() {
        // and some more here
    }
}

Why doesn't this work?

Class A is a valid managed bean and has a valid scope, just like class B. Even if I add @Producer to the static method, it won't change anything (which is fine, cause the idea of the static method is to call it, not to inject Builder anywhere).

like image 270
Mythica Avatar asked Feb 01 '11 20:02

Mythica


1 Answers

Dependency injection, while useful, is not magical. The way DI works is that when you ask the container for an instance of an object the container first constructs it (via new()) and then sets the dependencies (how this happens depends on your framework).

If you construct the entity yourself then the container has no idea you've constructed the entity and can't set the dependencies of the entity.

If you want to use a factory then most frameworks have some way of configuring the entity so that the container knows to make a static factory method call and not call the constructor of the entity. However, you still have to obtain your entity from the container.

Edit: This site seems to demonstrate how to use a factory in CDI.

like image 84
Pace Avatar answered Oct 21 '22 07:10

Pace