I just want to confirm that I fully understood the prerequisites for CDI to work. If I have a class A:
public class A {
@Inject private B b;
}
Here's the conditions needed for a class to be a managed bean (and hence, for the @Inject annotation to work on its fields/methods):
http://docs.oracle.com/javaee/6/tutorial/doc/gjfzi.html
Yes, @Inject works only inside a container because it is done using interceptors on method calls. When the container creates a bean it wrappes it in interceptors which perform injection, and in the case of instantiation using new no interceptors will be called during bean method invocation, and there will be no injection.
You may use BeanProvider.injectFields(myObject);
from Apache DeltaSpike.
Does CDI only work if the class requiring an injection was also created by CDI container?
Yes, that's pretty much it. The lifecycle of a ManagedBean
is controlled by the container and should never be instantiated with the new
keyword (BTW: the same is true for EJBs & Spring beans). If you need to create a new ManagedBean you will probably want to use a producer method.
While others have stated correctly that for the most part DI containers will not inject dependencies into bean that they did not instantiate this is not entirely true.
Spring has a wonderful feature that will autowire the bean when you create it using new A()
.
You just have to use AspectJ and mark your bean with the @Configurable annotation.
@Configurable
public class A {
@Inject private B b;
}
Its actually kind of an awesome feature cause you can do Active Record style POJO's while still honoring your DI (its in fact how Spring Roo does it).
You should also know that with Spring you can autowire a bean programmatically after its been instantiated with the AutowireCapableBeanFactory. This is how it typically autowires JUnit Test Case Classes because JUnit creates the test case classes.
Yes Spring is not CDI but in theory you could write your own @Configurable
for CDI or there is probably a CDI way of doing the above.
That being said the above is sort of a sophisticated feature (and kind of a hack) and as @JanGroth mentioned understaning the lifecycle bean management of the container is critical whether its CDI, Spring, Guice etc.