xml.xml
7.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ ]>
<chapter id="xml">
<title>Defining beans using XML</title>
<para>
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:
</para>
<itemizedlist>
<listitem>
<para>
when the implementation class comes from some preexisting library, or
</para>
</listitem>
<listitem>
<para>
when there should be multiple beans with the same implementation class.
</para>
</listitem>
</itemizedlist>
<para>
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.
</para>
<para>
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.
</para>
<para>
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.
</para>
<section>
<title>Declaring beans</title>
<para>
For each Java package, Weld defines a corresponding XML namespace. The namespace is formed by prepending
<literal>urn:java:</literal> to the Java package name. For the package <literal>com.mydomain.myapp</literal>,
the XML namespace is <literal>urn:java:com.mydomain.myapp</literal>.
</para>
<para>
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.
</para>
<para>
For example, the element <literal><util:Date/></literal> in the following XML fragment refers to the
class <literal>java.util.Date</literal>:
</para>
<programlisting role="XML"><![CDATA[<beans xmlns="urn:java:javax.beans"
xmlns:util="urn:java:java.util">
<util:Date/>
</beans>]]></programlisting>
<para>
And this is all the code we need to declare that <literal>Date</literal> is a bean! An instance of
<literal>Date</literal> may now be injected by any other bean:
</para>
<programlisting role="JAVA"><![CDATA[private @Inject Date date;]]></programlisting>
</section>
<section>
<title>Declaring bean metadata</title>
<para>
We can declare the scope, deployment type and interceptor binding types using direct child elements of the bean
declaration:
</para>
<programlisting role="XML"><![CDATA[<myapp:ShoppingCart>
<SessionScoped/>
<myfwk:Transactional requiresNew="true"/>
<myfwk:Secure/>
</myapp:ShoppingCart>]]></programlisting>
<para>We use exactly the same approach to specify names and qualifiers:</para>
<programlisting role="XML"><![CDATA[<util:Date>
<Named>currentTime</Named>
</util:Date>
<util:Date>
<SessionScoped/>
<myapp:Login/>
<Named>loginTime</Named>
</util:Date>
<util:Date>
<ApplicationScoped/>
<myapp:SystemStart/>
<Named>systemStartTime</Named>
</util:Date>]]></programlisting>
<para>
Where <literal>@Login</literal> and <literal>@SystemStart</literal> are qualifier annotations types.
</para>
<programlisting role="JAVA"><![CDATA[private @Inject Date currentTime;
private @Login Date loginTime;
private @SystemStart Date systemStartTime;]]></programlisting>
<para>As usual, a bean may support multiple qualifier types:</para>
<programlisting role="XML"><![CDATA[<myapp:AsynchronousChequePaymentProcessor>
<myapp:PayByCheque/>
<myapp:Asynchronous/>
</myapp:AsynchronousChequePaymentProcessor>]]></programlisting>
<para>
Interceptors and decorators are beans as well, so they may be declared just like any other bean:
</para>
<programlisting role="XML"><![CDATA[<myfwk:TransactionInterceptor>
<Interceptor/>
<myfwk:Transactional/>
</myfwk:TransactionInterceptor>]]></programlisting>
</section>
<section>
<title>Declaring bean members</title>
<para>
TODO!
</para>
</section>
<section>
<title>Declaring inline beans</title>
<para>Weld lets us define a bean at an injection point. For example:</para>
<programlisting role="XML"><![CDATA[<myapp:System>
<ApplicationScoped/>
<myapp:admin>
<myapp:Name>
<myapp:firstname>Gavin</myapp:firstname>
<myapp:lastname>King</myapp:lastname>
<myapp:email>gavin@hibernate.org</myapp:email>
</myapp:Name>
</myapp:admin>
</myapp:System>]]></programlisting>
<para>
The <literal><Name></literal> element declares a bean of scope <literal>@Dependent</literal> and class
<literal>Name</literal>, 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.
</para>
<para>
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!
</para>
</section>
<section>
<title>Using a schema</title>
<para>
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.
</para>
<programlisting role="XML"><![CDATA[<beans xmlns="urn:java:javax.beans"
xmlns:myapp="urn:java:com.mydomain.myapp"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:java:javax.beans http://java.sun.com/jee/beans-1.0.xsd
urn:java:com.mydomain.myapp http://mydomain.com/xsd/myapp-1.2.xsd">
<myapp:System>
...
</myapp:System>
</beans>]]></programlisting>
<para>
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.
</para>
</section>
<!--
vim:et:ts=3:sw=3:tw=120
-->
</chapter>