[jsr-314-open] getting behind CDI

Dan Allen dan.j.allen at gmail.com
Thu Dec 17 11:23:43 EST 2009


I'm going to venture out onto a limb here in hopes of leveraging the
influence of your professional recommendations. I ask that you read through
this message with an open, forward-looking mind.

I feel strongly that, as a group, we should provide a consistent
recommendation regarding the programming model of JSF by getting behind CDI.
Now, I realize there are Spring developers and supporters on this EG. So,
before going any further, I want to clarify that the point I am making
relates specifically to the native Java EE 6 technology stack. Spring has
always been a strong alternative to the native Java EE programming model and
continues to be a great companion of JSF. The common rival that we want to
downplay is JSF managed beans.

I made the following analogy in my JSF 2 talk at JSF Summit that sets the
stage for my advice:

Facelets replaces JSP as CDI replaces JSF managed beans

(Keep in mind CDI is not a programming model, but adds additional discovery
of a platform-defined managed beans)

When JSF was created, no other facility was available for defining
contextual managed beans. As of Java EE 6, there is now a platform-wide
definition of a managed bean. With the services of CDI, there is a way to
discover, produce, scope, inject, name and override beans. All of a sudden,
the injection facility, and limited number of services in the JSF managed
bean facility looks rudimentary in comparison. And the reality is, before
CDI, most developers likely used an alternative bean container anyway
(probably Spring) to define managed beans. So the JSF managed bean facility
has been falling out of favor for a long time.

But there is a more serious problem with continuing to recommend the use of
the JSF managed bean facility. The injections do not take the scope of the
injected bean into consideration. That means, you cannot inject a
request-scoped bean into a session-scoped bean without causing the
request-scoped bean to become a session-scoped bean through attachment. This
is a very typical occurance with having managed beans in a web application.
CDI not only keeps beans in different scopes loosely coupled, it hides the
scope at the injection point. Therefore this discrepency of JSF managed
beans alone could be enough to question their viability. (If you are a
type-safety advocate, CDI has that going for it over JSF managed beans as
well. And with @ManagedBean, you still can't scope a stateful EJB, which
could cut out an unnecessary middle layer).

Having stated my advice for recommending CDI over JSF managed beans, let me
address some common misconceptions that may be stopping you from embracing
CDI.
*
Isn't CDI heavyweight?*

No. CDI is extremely efficient. All bean definitions and injection points
are calculated at startup. The scanning process is localized to archives
that contain a beans.xml file, so the number of classes to scan is
reasonable. The scanner is pluggable, so it can leverage the scanning that
may already be taking place in the application server. I would estimate that
it doesn't take any longer than looking for @ManagedBean annotations on
classes. Also, proxies are used to manage scoped injections, meaning the
overhead of interceptors is not present.

*Doesn't CDI require extra setup?*

CDI is present in any Java EE 6 application server (full or web profile), so
you can depend on it being there. JSF 2 is part of the Java EE 6 platform,
which is one of it's greatest differentiators over competing web frameworks.
(Of course, other web frameworks could use CDI too, but that is a separate
point).

*But I won't be able to use CDI in a Servlet Container, right?*

Not true. The CDI reference implementation (Weld) provides a single
extension JAR (weld-servlet.jar) that you drop into your web application
archive and you get a full CDI environment (you just don't get EJBs, but
that's to be expected).

*What about older Java EE containers?*

The Weld servlet extension JAR could be added to an application deployed to
a pre-Java EE container and likely work just fine. Let the Weld team know
what doesn't work: https://jira.jboss.org/jira/browse/WELDX

*Isn't it easier just to get started with JSF 2 along?*

Use these Maven 2 archetypes to get started with JSF 2.0 + CDI 1.0 in a
jiffy: http://tinyurl.com/weld-archetypes (soon to be available in the Maven
Central Repository)

*But we worked hard to be able to define JSF managed beans with annotations*

Yes, when we did that Java EE 6 was not around and it was a good step
forward at the time. But 6 months has gone by and Java EE 6 is here, along
with CDI. It's time to embrace the improvements.

*Isn't CDI just a Red Hat thing*?

Of course not. We should all be behind CDI. As the spec lead, Red Hat worked
very hard to define a set of services for Java EE managed beans that would
make the development of enterprise applications simpler. That's exactly the
type of effort we all put in for the JSF 2 specification. (JSF 2 was forged
by all of us collectively. CDI has the same story). So CDI is your
technology, one that you can use in Java EE 6 or even outside of it. There
is no reason to back away from it.

Perhaps a lot of the heated debating over dependency injection turned you
off, but that heated debate really made the whole platform better because EG
members, like us, talked and worked things out in the end. I really want you
guys to view CDI as just as much part of our collective stack as the EL,
JSF, JPA and other successful technologies.

Showing users how to use @ManagedBean on a class and inject other managed
beans with @ManagedProperty or an EJB with @EJB is showing developers only a
portion of the value of this platform's programming model. We want to put
our best foot forward. That's why we show composite components in
presentations and not how to create a components in Java. We show Facelets,
not JSP. We want to make it seem as easy as it can be.

Rather than recommending:

@ManagedBean
@RequestScoped
public class BlogEditor {
   @ManagedProperty("#{blogDao}") BlogDao blogDao;
   // getters and setters required
}

We want to show them:

@Named
@RequestScoped
public class BlogEditor {
   @Inject BlogDao blogDao;
}

or even simpler, we can use the built-in @Model stereotype that combines
@Named and @RequestScoped

@Model
public class BlogEditor {
   @Inject BlogDao blogDao;
}

The only consolation is that they have to add an empty beans.xml to WEB-INF.

I'm asking you to consider my request to get behind CDI. We aren't talking
about a big change here. But the consistency of the message, and the power
that they get with CDI, will make a huge impact. I encourage you to read the
Weld reference guide as it very clearly explains what CDI is all about (if
it doesn't, tell us). http://tinyurl.com/weldrefguide

(I'll conclude by saying that if this were a Spring + JSF 2 talk, I won't
start by recommending @ManagedBean as a first step).

I welcome your feedback. I'll be glad to answer questions as well.

-Dan

-- 
Dan Allen
Senior Software Engineer, Red Hat | Author of Seam in Action
Registered Linux User #231597

http://mojavelinux.com
http://mojavelinux.com/seaminaction
http://www.google.com/profiles/dan.j.allen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jsr-314-open-mirror/attachments/20091217/0392271d/attachment.html 


More information about the jsr-314-open-mirror mailing list