Defining beans using XML
So far, we've seen plenty of examples of beans declared using annotations. However, there are a couple of
occasions when we can't use annotations to define the bean:
when the implementation class comes from some preexisting library, or
when there should be multiple beans with the same implementation class.
One way to address these problems is to write a producer method. Weld offers another option: declare the bean
using XML. This feature will hopefully one day be part of the CDI specification. Until then, it remains a portable
extension.
Many frameworks use XML to provide metadata relating to Java classes. However, Weld uses a very different approach
to specifying the names of Java classes, fields or methods to most other frameworks. Instead of writing class and
member names as the string values of XML elements and attributes, Weld lets you use the class or member name as
the name of the XML element.
The advantage of this approach is that you can write an XML schema that prevents spelling errors in your XML
document. It's even possible for a tool to generate the XML schema automatically from the compiled Java code. Or,
an integrated development environment could perform the same validation without the need for the explicit
intermediate generation step.
Declaring beans
For each Java package, Weld defines a corresponding XML namespace. The namespace is formed by prepending
urn:java: to the Java package name. For the package com.mydomain.myapp,
the XML namespace is urn:java:com.mydomain.myapp.
Java types belonging to a package are referred to using an XML element in the namespace corresponding to the
package. The name of the element is the name of the Java type. Fields and methods of the type are specified by
child elements in the same namespace. If the type is an annotation, members are specified by attributes of the
element.
For example, the element <util:Date/> in the following XML fragment refers to the
class java.util.Date:
]]>
And this is all the code we need to declare that Date is a bean! An instance of
Date may now be injected by any other bean:
Declaring bean metadata
We can declare the scope, deployment type and interceptor binding types using direct child elements of the bean
declaration:
]]>
We use exactly the same approach to specify names and qualifiers:
currentTime
loginTime
systemStartTime
]]>
Where @Login and @SystemStart are qualifier annotations types.
As usual, a bean may support multiple qualifier types:
]]>
Interceptors and decorators are beans as well, so they may be declared just like any other bean:
]]>
Declaring bean members
TODO!
Declaring inline beans
Weld lets us define a bean at an injection point. For example:
Gavin
King
gavin@hibernate.org
]]>
The <Name> element declares a bean of scope @Dependent and class
Name, with a set of initial field values. This bean has a special, container-generated
qualifier and is therefore injectable only to the specific injection point at which it is declared.
This simple but powerful feature allows the Weld XML format to be used to specify whole graphs of Java objects.
It's not quite a full databinding solution, but it's close!
Using a schema
If we want our XML document format to be authored by people who aren't Java developers, or who don't have
access to our code, we need to provide a schema. There's nothing specific to Weld about writing or using the
schema.
...
]]>
Writing an XML schema is quite tedious. Therefore, the Weld project will provide a tool which automatically
generates the XML schema from compiled Java code.