[jsr342-experts] Proposal for global CDI enablement
- From: Pete Muir <pmuir@...>
- To: cdi-dev <cdi-dev@...>, jsr342-experts@...
- Subject: [jsr342-experts] Proposal for global CDI enablement
- Date: Mon, 10 Dec 2012 14:52:03 +0100
I've been working with the Bill and Linda, the Java EE spec leads, as well as
with Jason, Stuart and Emmanuel at Red Hat, to come up with a proposal for
global enablement for CDI in Java EE 7. Based on Linda and Bill's poll of the
community, this appears to be much more popular than we had previously
thought, so we have decided to propose it, despite it being quite late into
the spec development. I think what we have come up with represents a good
approach to achieve it, and also addresses a long requested feature request,
that CDI should not consider every class a bean. Please let us know your
thoughts. If you aren't on the Java EE EG, or the observers list, or the same
for CDI, then please say, and I'll forward your thoughts.
Globally enabling CI would allow other specifications in the Java EE platform
to rely on CDI, and not have to provide an abstraction over DI services, such
as those introduced by JSF managed beans, and considered by JAX-RS, Batch and
* The startup time of Weld is O(n) with the number of beans. We assert that
it is not possible for a CDI impl to attain an O(1) startup time, therefore
globally enabling CDI will increase the startup time of Java EE servers. For
Red Hat, low startup time is a top priority.
* Compatibility with other users of JSR-330. By considering all deployments
as CDI deployments without any enablement marker, we will likely cause
deployments which used another JSR-330 implementation to fail. This would
have worked on Java EE 6. Other JSR-330 impls that fall into this camp are
Spring and Guice.
* Backwards compatibility. Some users may have intentionally not placed a
beans.xml into a deployment, but used CDI annotations, and enabled the beans
some other way, eg. via a portable extension.
* A large proportion of Java EE users 800/1000 indicate they want this
feature, thus meaning we should try to address it
We introduce the concept of a "bean defining annotation" and define that any
class in any deployment (including those with no beans.xml) with a bean
defining annotation is discovered and may be a CDI bean, and can participate
fully in the application. Any archive with a beans.xml continues to work in
the same way, such that all classes in the archive are discovered and may be
This addresses the startup time problem. Whilst a scan of classes is still
required, the impact on startup time is negligible:
* A Java EE server must scan all classes to discover other component defining
annotations such as EJBs, Servlet's, JAX-RS resources etc.
* This scan can be done at the bytecode level, with no need to classload the
class, which our research shows is the costly part of CDI startup
Any scope (normal scope or pseudo-scope) applied to a bean at source level is
a bean defining annotation (so you must add @Dependent to your class in order
to get it to be picked up as a dependent bean).
Only classes with a bean defining annotation, or with an annotation, or
meta-annotation, present specified by @WithAnnotations are passed to
ProcessAnnotatedType observers (the exact semantics are defined by CDI 1.1
PRD for @WithAnnotations). As mentioned above, if a ProcessAnnotatedType is
observed for a type without a bean defining annotation, as a result of having
an annotation present that is specified by @WithAnnotations, it may instruct
the container to add discover the class as a bean.
Every archive in a deployment would be considered a bean archive, simply with
differing contents depending on the presence of beans.xml
If a developer adds a beans.xml to their archive, behavior is as CDI 1.0. We
will add an attribute to beans.xml "auto-discover=true", which the user may
set to false in order to add a beans.xml and only have classes with a bean
defining annotation discovered, which allows beans.xml to be used as a
deployment descriptor but still limit the classes discovered.
OPEN ISSUE: Should auto-discover be false by default for beans.xml with
version 1.1. This would mean that adding a beans.xml would have no impact on
discovery for 1.1 apps, however it is a significant change from 1.0.
OPEN ISSUE: Should only scopes for which a CDI context exists be considered
component defining? This could introduce some thorny edge cases, but would
address the JSR-330 compatibility issue better.
OPEN ISSUE: Should we extend auto-discover in beans.xml to allow complete
disablement of scanning e.g.
OPEN ISSUE: How should the ProcessAnnotatedType event instruct the container
to discover a class as a bean? Perhaps something like event.discover(clazz)?
OPEN ISSUE: Should we integrate this with the package level scanning control
we have proposed for CDI 1.1?