How to limit what CDI considers to be managed beans? - java

I am coming at this question from many years of using spring and just starting to look at JEE7 and CDI.
In the Spring world you have to stick #Component on a bean to turn into spring bean that spring will inject with dependencies but in CDI it seems that there is no equivalent of #Component.
To me CDI seems to imply that every class in my web application will be considered a CDI bean which seems undesirable because I have lot of java classes that are not using injection and I would not want some one to just stick #Inject in those classes and have CDI do its magic.
Two questions:
How to restrict what CDI considers to be a managed bean in a jar file?
What is the benefit for CDI to consider every bean to be a managed bean?

Please see the documentation for bean-discovery-mode in beans.xml. This attribute was only made available in JEE7 and is not available in JEE6.

Related

Can I mix JEE and Spring annotations using Spring as CDI?

So, pretty straightforward question. Can I mix JEE annotations with Spring annotations on the same project? Are there any known issues with mixing both types of annotations?
For example, #Autowired and #Inject? #Named and #Qualifier?
Should Spring be able to solve injections without issues?
The reason I'm asking this is because I've encountered myself with some legacy code that uses Spring as CDI framework but 60% of the code uses JEE annotations. Some beans, however, are wired using #Autowired, there are also Spring ConfigProperties, etc.
I've already seen some weird behaviour, like classes not being injected, or #Named not being recognized by Spring, etc.
Spring does support CDI annotations, including #Inject, #Named, #Qualifier, ... But it comes with some limitations.
If some class is not injected, or #Named is not recognized, I think it is likely a configuration problem.

Inject Instance<Interface> : Spring and CDI compatibility

I am wondering how can I use the Instance in JUnit4 with Spring
#Inject
Instance<IMyInterface> interfaces;
If I use
#Inject
List<IMyInterface> interfaces;
It works in Spring but not with CDI.
Also, we can use Provider with both CDI and Spring but it's not Iterable.
The #Inject annotation comes from JSR-330-Dependency Injection for Java. Spring knows this annotation and briefly said, Spring treats it as an alternative to #Autowired. That's it.
However, the Instance is part of JSR 299 - Contexts & Dependency Injection. You can have a look at the definition in CDI specifications.
Spring DI is absolutely different and does not implement JSR-299 (CDI) or any other standard. It does not even have a separate API and implementations and everything is just glued together. Therefore, injecting an Instace is not possible with Spring.

Injected EJB Reference Lost in ViewScoped JSF Bean

I've seen quite a bit of discussion on the injection of EJBs into ViewScoped JSF-managed beans. It seems acceptable practice to do so.
I'm attempting to change one of the beans in my application from RequestScoped to ViewScoped to add some additional needed functionality.
I've modified the EJB classes to ensure that everything is serializable. When my JSF bean is created, the EJBs are initially accessible. However, when a user action fires a method in the bean that tries to invoke an EJB method, a NullPointerException is thrown.
As soon as I switch the bean from ViewScoped back to RequestScoped, everything works fine.
Could this be a fault in the implementation of JSF being used? This application is using MyFaces 2.1.12 and runs on Websphere 7.0.
Thanks.
CDI as a framework on its own doesn't know anything about Views. Thus injecting in a #ViewScoped bean won't work.
This is one of the major disadvantages of using JSF and CDI together. But you are not the first one to encounter this problem.
If you are stuck with JSF 2.1 Implementations, frameworks like Apache CODI or Seam 3 will extend your CDI in a way so you can also #Inject in #ViewScoped beans.
If you are able to upgrade to JSF 2.2 (which I would recommended you to do), this CDI extension will be a native part of the JSF implementation and you are able to use both together without further ado. See this explanation.

Spring dependency injection, to use #Named or #Resource?

There are two separate annotations to perform dependency injection by name in Spring, javax.annotation.Resource and javax.inject.Named. The documentation at Spring indicates #Resource should be used for injection by name:
If you intend to express annotation-driven injection by name, do not
primarily use #Autowired, even if is technically capable of referring
to a bean name through #Qualifier values. Instead, use the JSR-250
#Resource annotation, which is semantically defined to identify a
specific target component by its unique name, with the declared type
being irrelevant for the matching process.
The above is a bit confusing, as Spring is only advocating #Resource instead of #Autowired combined with #Qualifer. There is no mention of #Named until later in the documentation.
JSR-250 defines #Resource, whereas JSR-330 defines #Inject and #Named. I know they can be mixed-and-matched within Spring fairly easily. Which JSR to use?
It seems like portability with Guice and CDI would be nice, and hence to use the JSR-330 annotations. On the other hand, the documentation also points out at a couple of limitations within Spring when using JSR-330 annotations.
What is the best practice (if there is one) for annotation injection-by-name?
Thank you.
#Resource is older and is supported since Spring 2.5 while #Named support has been added in Spring 3.0 and both of them can be used to achieve the same purpose of injection-by-name.
When using Spring, my concerns for preferring one over the other would be backward compatibility with Spring 2.5 and whether javax.inject can be added/assumed-to-be on the classpath or not.

Injecting parameters into Beans, CDI bean VS JSF bean

after some experimenting, I have been able to inject my GET-parameters into an #ManagedBean (thus, a JSF) bean using #ManagedProperty and some EL.
Now, except the approach from reading the parameter map from FacesContext.getCurrentInstance().getExternalContext(), I have not been able to inject my GET-parameters into an #Named (thus, a CDI-) bean.
And so, I have been reading about advantages and disadvantages of JSF beans and CDI beans.
In short, I am stuck with two questions:
1st. Will I experience any disadvantages in using JSF beans over CDI beans?
2nd. If so, is there a clean way to inject my GET-parameters into a CDI bean?
I hope that I don't start a flamewar here, but it's certainly safe to say that CDI scopes and dependency-injection mechanisms cover far more ground than JSF scopes do. Generally speaking, you are better off with CDI scopes - but one could go into almost arbitrary details here.
Concerning you problem: Seam Solder brings - among many other things - http-parameter-injection. Check this out.
Update:
Should you be afraid of integrating Solder into your project (don't be!), take a look at the relevant source-code which does the magic. You can easily copy it into your project - it's just that the developers behind Solder had a few more cornercases in their mind than you would probably come up with on the spot.

Categories

Resources