You may be wondering, if beans are not described using XML, why do we need beans.xml at all? In particular, why do you need it if you don’t have anything that you would need the bean descriptor to enable (alternatives, interceptors or decorators)?
There are two things about CDI that we need to keep in mind:
-
CDI does not require any special declaration on a Java class to enable it to be injected - that’s right, no annotation or XML declaration at all!
-
CDI does not define any special kind of module - CDI beans can be deployed in a library jar, EJB jar, war, rar, or JVM classpath directory.
The CDI specification calls the process of identifying beans in modules bean discovery.
So there are potentially a lot of classes in the classpath which might be beans! We don’t want to force the container to scan every one of those classes at startup and build its internal metamodel for each of them. This really could make bean discovery very slow.
But there’s another reason we need to give the user some control over which classes are available for injection. We don’t want every class in the classpath to potentially match an injection point, including classes that were never intended to be injected into things. This would force the developer to have to use qualifiers much more often to disambiguate injection points.
So we have two choices. We could have the developer:
-
explicitly exclude modules which do not contain beans, or
-
explicitly declare modules which do contain beans.
Hopefully you agree that the second option is a much better way to go. In following this approach, CDI has the notion of a bean archive. A bean archive is just a module that has a file named beans.xml in the META-INF directory. The container looks for beans in bean archives. It ignores other modules.
Now, you might be wondering if we’ve got the granularity wrong here. Why should module be the right criteria to use for including/excluding a class? Why not consider:
-
a class-level annotation,
-
the package,
-
some type it implements or extends, or
-
some naming convention?
We’ve got the first option covered. Annotate a bean @Alternative
, or with an alternative stereotype, and it will be considered disabled by CDI, as long as you don’t explicitly enable it in beans.xml. That’s not quite the same thing as excluding the class from scanning altogether, but it’s close. (One difference is that a portable extension with still get a ProcessAnnotatedType
event for that class).
A future version of CDI might allow you to declare excluded packages in beans.xml. Excluding a bean by type or naming convention isn’t really that appealing. In the world of CDI, we use stereotypes for identifying architectural roles. We don’t use marker interfaces or naming conventions. Names really shouldn’t affect functionality as it is too fragile.
Enough theory, what elements are available in beans.xml?