Reputation: 1
I have three questions
Upvotes: -1
Views: 916
Reputation: 6753
Firstly, EJB and CDI are two different specifications with different limitations and goals. Later on in Java/Jakarta EE evolution, CDI created a bridge between the two where it considers all EJB beans to also be CDI beans (the internals of which are more complex and I won't go into now) but otherwise they are still different specs so don't conflate them.
In CDI, beans can be either managed beans or producer methods/fields. Managed beans are typically a java class which can (or in some cases must) have certain annotations to be picked up as a bean. There are some limitations as to how a managed bean looks. See this section of specification (CDI 4, Jakarta EE 10) for further information. Producer methods/fields are a way to declare a bean while also providing an instance of the bean yourself instead of letting CDI create it. In both cases, CDI then manages the bean for its lifecycle, which is typically controlled by the scope of the bean (i.e. @RequestScoped
).
However, that's not all there is to it. You mentioned discovery and that's part of the process. There are three discovery modes - none
, all
, annotated
- which can be declared in beans.xml
. These control which beans will be found and if they need any kind of annotation to be recognized as beans. none
simply means no beans, all
means that all classes will be picked up as potential beans, even without annotations. And lastly, annotated
will only pick up beans that have a so called bean defining annotation
. These include scope annotations, stereotypes, and interceptor annotation. See this part of spec (CDI 4).
Note that prior to CDI 4, default discovery mode was all
. With CDI 4 and onwards, it is annotated
!
To your second question - SpecialLogger
has no no-args constructor and has one constructor with parameters (LogConfiguration
) and this constructor isn't annotated with @Inject
. Therefore, CDI doesn't know how to create an instance of this object. Note that annotating the constructor with @Inject
effectively tells CDI that all of its parameters are also CDI beans that it should know how to instantiate which is not going to be the case in this example.
This brings me to your last question. A producer is typically useful for when it isn't easy or even possible to have an instance of the class created automatically by CDI, but there is still value in handling the instance as a CDI bean. Once you define a producer for SpecialLogger
, you can then normally @Inject SpecialLogger
in your code. In the end, user won't know if their bean is a product of CDI class instantiation or a producer method. Since bean types of producer method are governed by transitive closure on method's return type, you can also choose to return one of several subclasses based on some config options etc. Overall, it gives you more control over how to create and initialize an object before you hand it over to CDI but at the cost of not having this object injected (since it is you who creates it and not CDI).
Upvotes: 3