beans.xml
47.1 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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ ]>
<chapter id="beanscdi">
<title>More about beans</title>
<para>
A bean is usually an application class that contains business logic. It may be called directly from Java code,
or it may be invoked via the Unified EL. A bean may access transactional resources. Dependencies between beans
are managed automatically by the container. Most beans are <emphasis>stateful</emphasis> and
<emphasis>contextual</emphasis>. The lifecycle of a bean is always managed by the container.
</para>
<para>
Let's back up a second. What does it really mean to be <emphasis>contextual</emphasis>? Since beans may be
stateful, it matters <emphasis>which</emphasis> bean instance I have. Unlike a stateless component model (for
example, stateless session beans) or a singleton component model (such as servlets, or singleton beans),
different clients of a bean see the bean in different states. The client-visible state depends upon which
instance of the bean the client has a reference to.
</para>
<para>
However, like a stateless or singleton model, but <emphasis>unlike</emphasis> stateful session beans, the
client does not control the lifecycle of the instance by explicitly creating and destroying it. Instead, the
<emphasis>scope</emphasis> of the bean determines:
</para>
<itemizedlist>
<listitem>
<para>the lifecycle of each instance of the bean and</para>
</listitem>
<listitem>
<para>which clients share a reference to a particular instance of the bean.</para>
</listitem>
</itemizedlist>
<para>
For a given thread in a CDI application, there may be an <emphasis>active context</emphasis> associated with
the scope of the bean. This context may be unique to the thread (for example, if the bean is request scoped),
or it may be shared with certain other threads (for example, if the bean is session scoped) or even all other
threads (if it is application scoped).
</para>
<para>
Clients (for example, other beans) executing in the same context will see the same instance of the bean. But
clients in a different context may see a different instance (depending on the relationship between the
contexts).
</para>
<para>
One great advantage of the contextual model is that it allows stateful beans to be treated like services! The
client need not concern itself with managing the lifecycle of the bean it's using, <emphasis>nor does it even
need to know what that lifecycle is.</emphasis> Beans interact by passing messages, and the bean implementations
define the lifecycle of their own state. The beans are loosely coupled because:
</para>
<itemizedlist>
<listitem>
<para>they interact via well-defined public APIs</para>
</listitem>
<listitem>
<para>their lifecycles are completely decoupled</para>
</listitem>
</itemizedlist>
<para>
We can replace one bean with another different bean that implements the same interface and has a different lifecycle
(a different scope) without affecting the other bean implementation. In fact, CDI defines a simple facility for
overriding bean implementations at deployment time, as we will see in <xref linkend="alternatives"/>.
</para>
<para>
Note that not all clients of a bean are beans themselves. Other objects such as servlets or message-driven
beans—which are by nature not injectable, contextual objects—may also obtain references to beans by
injection.
</para>
<section id="bean-anatomy">
<title>The anatomy of a bean</title>
<para>Enough hand-waving. More formally, the anatomy of a bean, according to the spec:</para>
<blockquote>
<para>A bean comprises the following attributes:</para>
<itemizedlist>
<listitem><para>A (nonempty) set of bean types</para></listitem>
<listitem><para>A (nonempty) set of qualifiers</para></listitem>
<listitem><para>A scope</para></listitem>
<listitem><para>Optionally, a bean EL name</para></listitem>
<listitem><para>A set of interceptor bindings</para></listitem>
<listitem><para>A bean implementation</para></listitem>
</itemizedlist>
<para>Furthermore, a bean may or may not be an alternative.</para>
</blockquote>
<para>Let's see what all this new terminology means.</para>
<section>
<title>Bean types, qualifiers and dependency injection</title>
<para>
Beans usually acquire references to other beans via dependency injection. Any injected attribute specifies a
"contract" that must be satisfied by the bean to be injected. The contract is:
</para>
<itemizedlist>
<listitem><para>a bean type, together with</para></listitem>
<listitem><para>a set of qualifiers.</para></listitem>
</itemizedlist>
<para>
A bean type is a user-defined class or interface; a type that is client-visible. If the bean is an EJB
session bean, the bean type is the <literal>@Local</literal> interface or bean-class local view. A bean
may have multiple bean types. For example, the following bean has four bean types:
</para>
<programlisting role="JAVA"><![CDATA[public class BookShop
extends Business
implements Shop<Book> {
...
}]]></programlisting>
<para>
The bean types are <literal>BookShop</literal>, <literal>Business</literal> and
<literal>Shop<Book></literal>, as well as the implicit type <literal>java.lang.Object</literal>.
(Notice that a parameterized type is a legal bean type).
</para>
<para>
Meanwhile, this session bean has only the local interfaces <literal>BookShop</literal>,
<literal>Auditable</literal> and <literal>java.lang.Object</literal> as bean types, since the bean class,
<literal>BookShopBean</literal> is not a client-visible type.
</para>
<programlisting role="JAVA"><![CDATA[@Stateful
public class BookShopBean
extends Business
implements BookShop, Auditable {
...
}]]></programlisting>
<note>
<para>
The bean types of a session bean include local interfaces and the bean class local view (if any).
EJB remote interfaces are not considered bean types of a session bean. You can't inject an EJB using
its remote interface unless you define a <emphasis>resource</emphasis>, which we'll meet in
<xref linkend="resources"/>.
</para>
</note>
<para>
Bean types may be restricted to an explicit set by annotating the bean with the <literal>@Typed</literal>
annotation and listing the classes that should be bean types. For instance, the bean types of this bean have
been restricted to <literal>Shop<Book></literal>, together with <literal>java.lang.Object</literal>:
</para>
<programlisting role="JAVA"><![CDATA[@Typed(Shop.class)
public class BookShop
extends Business
implements Shop<Book> {
...
}]]></programlisting>
<para>
Sometimes, a bean type alone does not provide enough information for the container to know which bean to inject.
For instance, suppose we have two implementations of the <literal>PaymentProcessor</literal> interface:
<literal>CreditCardPaymentProcessor</literal> and <literal>DebitPaymentProcessor</literal>. Injecting a field of
type <literal>PaymentProcessor</literal> introduces an ambiguous condition. In these cases, the client must
specify some additional quality of the implementation it is interested in. We model this kind of "quality" using
a qualifier.
</para>
<para>
A qualifier is a user-defined annotation that is itself annotated <literal>@Qualifer</literal>. A qualifier
annotation is an extension of the type system. It lets us disambiguate a type without having to fall back to
string-based names. Here's an example of a qualifier annotation:
</para>
<programlisting role="JAVA"><![CDATA[@Qualifier
@Target({TYPE, METHOD, PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface CreditCard {}]]></programlisting>
<para>
You may not be used to seeing the definition of an annotation. In fact, this might be the first time you've
encountered one. With CDI, annotation definitions will become a familiar artifact as you'll be creating them
from time to time.
</para>
<tip>
<para>
Pay attention to the names of the built-in annotations in CDI and EJB. You'll notice that they are
often adjectives. We encourage you to follow this convention when creating your custom annotations,
since they serve to describe the behaviors and roles of the class.
</para>
</tip>
<para>
Now that we have defined a qualifier annotation, we can use it to disambiguate an injection point. The
following injection point has the bean type <literal>PaymentProcessor</literal> and qualifier
<literal>@CreditCard</literal>:
</para>
<programlisting role="JAVA"><![CDATA[@Inject @CreditCard PaymentProcessor paymentProcessor]]></programlisting>
<note>
<para>
If an injection point does not explicitly specify a qualifier, it has the default qualifier,
<literal>@Default</literal>.
</para>
</note>
<para>
For each injection point, the container searches for a bean which satisfies the contract, one which has
the bean type and all the qualifiers. If it finds exactly one matching bean, it injects an instance of
that bean. If it doesn't, it reports an error to the user.
</para>
<para>
How do we specify that qualifiers of a bean? By annotating the bean class, of course! The following bean
has the qualifier <literal>@CreditCard</literal> and implements the bean type <literal>PaymentProcessor</literal>.
Therefore, it satisfies our qualified injection point:
</para>
<programlisting role="JAVA"><![CDATA[@CreditCard
public class CreditCardPaymentProcessor
implements PaymentProcessor { ... }]]></programlisting>
<note>
<para>
If a bean does not explicitly specify a qualifier, it has the default qualifier, <literal>@Default</literal>.
</para>
</note>
<!--
<note>
<para>
All beans have the qualifier, <literal>@Any</literal>.
</para>
</note>
-->
<para>
That's not quite the end of the story. CDI also defines a simple <emphasis>resolution rule</emphasis> that helps
the container decide what to do if there is more than one bean that satisfies a particular contract. We'll get
into the details in <xref linkend="injection"/>.
</para>
<!--
<tip>
<para>
If you're expecting more than one bean to satisfy the contract, you can inject an <literal>Instance</literal>,
object which let's you iterate over all the beans which satisfy the contract. For example, we can iterate
over all our implementations of <literal>PaymentProcessor</literal> using:
</para>
<programlisting role="JAVA">@Inject void init(@Any Instance<PaymentProcessor> paymentProcessorInstance) {
for (PaymentProcessor pp: paymentProcessorInstance) { ... }
}</programlisting>
</tip>
-->
</section>
<section>
<title>Scope</title>
<!-- I wonder whether the explaination of contextual above would fit better here -->
<para>
The <emphasis>scope</emphasis> of a bean defines the lifecycle and visibility of its instances.
The CDI context model is extensible, accommodating arbitrary scopes. However, certain important scopes are
built into the specification, and provided by the container. Each scope is represented by an annotation
type.
</para>
<para>
For example, any web application may have <emphasis>session scoped</emphasis> bean:
</para>
<programlisting role="JAVA"><![CDATA[public @SessionScoped
class ShoppingCart implements Serializable { ... }]]></programlisting>
<para>An instance of a session-scoped bean is bound to a user session
and is shared by all requests that execute in the context of that session.</para>
<note>
<para>
Keep in mind that once a bean is bound to a context, it remains in that context until the context is
destroyed. There is no way to manually remove a bean from a context. If you don't want the bean to sit
in the session indefinitely, consider using another scope with a shorted lifespan, such as the request
or conversation scope.
</para>
</note>
<para>
If a scope is not explicitly specified, then the bean belongs to a special scope called the
<emphasis>dependent pseudo-scope</emphasis>. Beans with this scope live to serve the object into which they
were injected, which means their lifecycle is bound to the lifecycle of that object.
</para>
<para>We'll talk more about scopes in <xref linkend="scopescontexts"/>.</para>
</section>
<section>
<title>EL name</title>
<para>
If you want to reference a bean in non-Java code that supports Unified EL expressions, for example, in a
JSP or JSF page, you must assign the bean an <emphasis>EL name</emphasis>.
</para>
<para>
The EL name is specified using the <literal>@Named</literal> annotation, as shown here:
</para>
<programlisting role="JAVA"><![CDATA[public @SessionScoped @Named("cart")
class ShoppingCart implements Serializable { ... }]]></programlisting>
<para>Now we can easily use the bean in any JSF or JSP page:</para>
<programlisting role="XML"><![CDATA[<h:dataTable value="#{cart.lineItems}" var="item">
...
</h:dataTable>]]></programlisting>
<note>
<para>
The <literal>@Named</literal> annotation is not what makes the class a bean. Most classes in a bean
archive are already recognized as beans. The <literal>@Named</literal> annotation just makes it
possible to reference the bean from the EL, most commonly from a JSF view.
</para>
</note>
<para>
We can let CDI choose a name for us by leaving off the value of the <literal>@Named</literal> annotation:
</para>
<programlisting role="JAVA"><![CDATA[public @SessionScoped @Named
class ShoppingCart implements Serializable { ... }]]></programlisting>
<para>
The name defaults to the unqualified class name, decapitalized; in this case,
<literal>shoppingCart</literal>.
</para>
</section>
<!-- TODO the alternative section needs to be spruced up to support the text that comes in subsequent chapters.
The reader needs to feel confident than they would know how to create an alternative and enable it. -->
<section>
<title>Alternatives</title>
<para>
We've already seen how qualifiers let us choose between multiple implementations of an interface
at development time. But sometimes we have an interface (or other bean type) whose implementation
varies depending upon the deployment environment. For example, we may want to use a mock
implementation in a testing environment. An <emphasis>alternative</emphasis> may be declared by
annotating the bean class with the <literal>@Alternative</literal> annotation.
</para>
<programlisting role="JAVA"><![CDATA[public @Alternative
class MockPaymentProcessor extends PaymentProcessorImpl { ... }]]></programlisting>
<para>
We normally annotate a bean <literal>@Alternative</literal> only when there is some other
implementation of an interface it implements (or of any of its bean types). We can choose between
alternatives at deployment time by <emphasis>selecting</emphasis> an alternative in the CDI
deployment descriptor <literal>META-INF/beans.xml</literal> of the jar or Java EE module that uses
it. Different modules can specify that they use different alternatives.
</para>
<para>
We cover alternatives in more detail in <xref linkend="alternatives"/>.
</para>
</section>
<section>
<title>Interceptor binding types</title>
<para>
You might be familiar with the use of interceptors in EJB 3.0. In Java EE 6, this functionality has
been generalized to work with other managed beans. That's right, you no longer have to make your bean
an EJB just to intercept its methods. Holler. So what does CDI have to offer above and beyond that? Well,
quite a lot actually. Let's cover some background.
</para>
<para>
The way that interceptors were defined in Java EE 5 was counter-intuitive. You were required to specify the
<emphasis>implementation</emphasis> of the interceptor directly on the <emphasis>implementation</emphasis>
of the EJB, either in the <literal>@Interceptors</literal> annotation or in the XML descriptor. You might as
well just put the interceptor code <emphasis>in</emphasis> the implementation! Second, the order in which
the interceptors are applied is taken from the order in which they are declared in the annotation or the XML
descriptor. Perhaps this isn't so bad if you're applying the interceptors to a single bean. But, if you are
applying them repeatedly, then there's a good chance that you'll inadvertently define a different order for
different beans. Now that's a problem.
</para>
<para>
CDI provides a new approach to binding interceptors to beans that introduces a level of indirection (and
thus control). We must define an <emphasis>interceptor binding type</emphasis> to describe the behavior
implemented by the interceptor.
</para>
<para>
An interceptor binding type is a user-defined annotation that is itself annotated <literal>@InterceptorBinding</literal>.
It lets us bind interceptor classes to bean classes with no direct dependency between the two classes.
</para>
<programlisting role="JAVA"><![CDATA[@InterceptorBinding
@Inherited
@Target( { TYPE, METHOD })
@Retention(RUNTIME)
public @interface Transactional {}]]></programlisting>
<para>
The interceptor that implements transaction management declares this annotation:
</para>
<programlisting role="JAVA"><![CDATA[public @Transactional @Interceptor
class TransactionInterceptor { ... }]]></programlisting>
<para>
We can apply the interceptor to a bean by annotating the bean class with the same interceptor binding type:
</para>
<programlisting role="JAVA"><![CDATA[public @SessionScoped @Transactional
class ShoppingCart implements Serializable { ... }]]></programlisting>
<para>
Notice that <literal>ShoppingCart</literal> and <literal>TransactionInterceptor</literal> don't know
anything about each other.
</para>
<para>
Interceptors are deployment-specific. (We don't need a <literal>TransactionInterceptor</literal> in our
unit tests!) By default, an interceptor is disabled. We can enable an interceptor using the CDI deployment
descriptor <literal>META-INF/beans.xml</literal> of the jar or Java EE module. This is also where we
specify the interceptor ordering.
</para>
<para>
We'll discuss interceptors, and their cousins, decorators, in <xref linkend="interceptors"/> and <xref
linkend="decorators"/>.
</para>
</section>
</section>
<section>
<title>What kinds of classes are beans?</title>
<para>
We've already seen two types of beans: JavaBeans and EJB session beans. Is that the whole story? Actually,
it's just the beginning. Let's explore the various kinds of beans that CDI implementations must support
out-of-the-box.
</para>
<section>
<title>Managed beans</title>
<para>
A managed bean is a Java class. The basic lifecycle and semantics of a managed bean are defined by the
Managed Beans specification. You can explicitly declare a managed bean by annotating the bean class
<literal>@ManagedBean</literal>, but in CDI you don't need to. According to the specification, the CDI
container treats any class that satisfies the following conditions as a managed bean:
</para>
<blockquote>
<itemizedlist>
<listitem>
<para>It is not a non-static inner class.</para>
</listitem>
<listitem>
<para>It is a concrete class, or is annotated <literal>@Decorator</literal>.</para>
</listitem>
<listitem>
<para>
It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in
<literal>ejb-jar.xml</literal>.
</para>
</listitem>
<listitem>
<para>It does not implement <literal>javax.enterprise.inject.spi.Extension</literal>.</para>
</listitem>
<listitem>
<para>
It has an appropriate constructor—either:
</para>
<itemizedlist>
<listitem>
<para>the class has a constructor with no parameters, or</para>
</listitem>
<listitem>
<para>the class declares a constructor annotated <literal>@Inject</literal>.</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</blockquote>
<note>
<para>
According to this definition, JPA entities are technically managed beans. However, entities have their own
special lifecycle, state and identity model and are usually instantiated by JPA or using <literal>new</literal>.
Therefore we don't recommend directly injecting an entity class. We especially recommend against assigning
a scope other than <literal>@Dependent</literal> to an entity class, since JPA is not able to persist
injected CDI proxies.
</para>
</note>
<para>The unrestricted set of bean types for a managed bean contains the bean class, every superclass and all
interfaces it implements directly or indirectly.</para>
<para>If a managed bean has a public field, it must have the default scope <literal>@Dependent</literal>.</para>
<para>Managed beans support the <literal>@PostConstruct</literal> and <literal>@PreDestroy</literal> lifecycle
callbacks.</para>
<para>
Session beans are also, technically, managed beans. However, since they have their own special lifecycle and
take advantage of additional enterprise services, the CDI specification considers them to be a different
kind of bean.
</para>
</section>
<section>
<title>Session beans</title>
<para>
Session beans belong to the EJB specification. They have a special lifecycle, state management and concurrency
model that is different to other managed beans and non-managed Java objects. But session beans participate in
CDI just like any other bean. You can inject one session bean into another session bean, a managed bean into a
session bean, a session bean into a managed bean, have a managed bean observe an event raised by a session bean,
and so on.
</para>
<note>
<para>
Message-driven and entity beans are by nature non-contextual objects and may not be injected into other
objects. However, message-driven beans can take advantage of some CDI functionality, such as dependency
injection, interceptors and decorators. In fact, CDI will perform injection into any session or
message-driven bean, even those which are not contextual instances.
</para>
</note>
<para>
The unrestricted set of bean types for a session bean contains all local interfaces of the bean and their
superinterfaces. If the session bean has a bean class local view, the unrestricted set of bean types
contains the bean class and all superclasses. In addition, <literal>java.lang.Object</literal> is a bean
type of every session bean. But remote interfaces are <emphasis>not</emphasis> included in the set of bean
types.
</para>
<para>There's no reason to explicitly declare the scope of a stateless session bean or singleton session bean.
The EJB container controls the lifecycle of these beans, according to the semantics of the <literal>@Stateless</literal>
or <literal>@Singleton</literal> declaration. On the other hand, a stateful session bean may have any scope.</para>
<para>
Stateful session beans may define a <emphasis>remove method</emphasis>, annotated <literal>@Remove</literal>,
that is used by the application to indicate that an instance should be destroyed. However, for a contextual
instance of the bean—an instance under the control of CDI—this method may only be called by the
application if the bean has scope <literal>@Dependent</literal>. For beans with other scopes, the application
must let the container destroy the bean.
</para>
<para>
So, when should we use a session bean instead of a plain managed bean? Whenever we need the advanced enterprise
services offered by EJB, such as:
</para>
<itemizedlist>
<listitem>
<para>method-level transaction management and security,</para>
</listitem>
<listitem>
<para>concurrency management,</para>
</listitem>
<listitem>
<para>instance-level passivation for stateful session beans and
instance-pooling for stateless session beans,</para>
</listitem>
<listitem>
<para>remote or web service invocation, or</para>
</listitem>
<listitem>
<para>timers and asynchronous methods,</para>
</listitem>
</itemizedlist>
<para>When we don't need any of these things, an ordinary managed bean will serve just fine.</para>
<para>
Many beans (including any <literal>@SessionScoped</literal> or <literal>@ApplicationScoped</literal>
beans) are available for concurrent access. Therefore, the concurrency management provided by EJB 3.1
is especially useful. Most session and application scoped beans should be EJBs.
</para>
<para>
Beans which hold references to heavy-weight resources, or hold a lot of internal state benefit from the
advanced container-managed lifecycle defined by the EJB stateless/stateful/singleton model, with its
support for passivation and instance pooling.
</para>
<para>
Finally, it's usually obvious when method-level transaction management, method-level security, timers,
remote methods or asynchronous methods are needed.
</para>
<para>
The point we're trying to make is: use a session bean when you need the services it provides, not just
because you want to use dependency injection, lifecycle management, or interceptors. Java EE 6 provides
a graduated programming model. It's usually easy to start with an ordinary managed bean, and later turn
it into an EJB just by adding one of the following annotations: <literal>@Stateless</literal>,
<literal>@Stateful</literal> or <literal>@Singleton</literal>.
</para>
<para>
On the other hand, don't be scared to use session beans just because you've heard your friends say
they're "heavyweight". It's nothing more than superstition to think that something is "heavier" just
because it's hosted natively within the Java EE container, instead of by a proprietary bean container
or dependency injection framework that runs as an additional layer of obfuscation. And as a general
principle, you should be skeptical of folks who use vaguely defined terminology like "heavyweight".
</para>
</section>
<section>
<title>Producer methods</title>
<para>
Not everything that needs to be injected can be boiled down to a bean class instantiated by the container
using <literal>new</literal>. There are plenty of cases where we need additional control. What if we need
to decide at runtime which implementation of a type to instantiate and inject? What if we need to inject
an object that is obtained by querying a service or transactional resource, for example by executing a JPA
query?
</para>
<para>
A <emphasis>producer method</emphasis> is a method that acts as a source of bean instances. The method
declaration itself describes the bean and the container invokes the method to obtain an instance of the
bean when no instance exists in the specified context. A producer method lets the application take full
control of the bean instantiation process.
</para>
<para>
A producer method is declared by annotating a method of a bean class with the <literal>@Produces</literal>
annotation.
</para>
<programlisting role="JAVA"><![CDATA[@ApplicationScoped
public class RandomNumberGenerator {
private Random random = new Random(System.currentTimeMillis());
@Produces @Named @Random int getRandomNumber() {
return random.nextInt(100);
}
}]]></programlisting>
<para>
We can't write a bean class that is itself a random number. But we can certainly write a method that returns
a random number. By making the method a producer method, we allow the return value of the method—in this
case an <literal>Integer</literal>—to be injected. We can even specify a qualifier—in this case
<literal>@Random</literal>, a scope—which in this case defaults to <literal>@Dependent</literal>,
and an EL name—which in this case defaults to <literal>randomNumber</literal> according to the JavaBeans
property name convention. Now we can get a random number anywhere:
</para>
<programlisting role="JAVA"><![CDATA[@Inject @Random int randomNumber;]]></programlisting>
<para>
Even in a Unified EL expression:
</para>
<programlisting><![CDATA[<p>Your raffle number is #{randomNumber}.</p>]]></programlisting>
<para>
A producer method must be a non-abstract method of a managed bean class or session bean class. A producer
method may be either static or non-static. If the bean is a session bean, the producer method must be either
a business method of the EJB or a static method of the bean class.
</para>
<para>
The bean types of a producer method depend upon the method return type:
</para>
<itemizedlist>
<listitem>
<para>
If the return type is an interface, the unrestricted set of bean types contains the return type, all
interfaces it extends directly or indirectly and <literal>java.lang.Object</literal>.
</para>
</listitem>
<listitem>
<para>
If a return type is primitive or is a Java array type, the unrestricted set of bean types contains
exactly two types: the method return type and <literal>java.lang.Object</literal>.
</para>
</listitem>
<listitem>
<para>
If the return type is a class, the unrestricted set of bean types contains the return type, every
superclass and all interfaces it implements directly or indirectly.
</para>
</listitem>
</itemizedlist>
<note>
<para>
Producer methods and fields may have a primitive bean type. For the purpose of resolving dependencies,
primitive types are considered to be identical to their corresponding wrapper types in
<literal>java.lang</literal>.
</para>
</note>
<para>
If the producer method has method parameters, the container will look for a bean that satisfies the type
and qualifiers of each parameter and pass it to the method automatically—another form of
dependency injection.
</para>
<programlisting role="JAVA"><![CDATA[@Produces Set<Roles> getRoles(User user) {
return user.getRoles();
}]]></programlisting>
<para>We'll talk much more about producer methods in <xref linkend="producermethods"/>.</para>
</section>
<section>
<title>Producer fields</title>
<para>
A <emphasis>producer field</emphasis> is a simpler alternative to a producer method. A producer field is
declared by annotating a field of a bean class with the <literal>@Produces</literal> annotation—the
same annotation used for producer methods.
</para>
<programlisting role="JAVA"><![CDATA[public class Shop {
@Produces PaymentProcessor paymentProcessor = ....;
@Produces @Catalog List<Product> products = ....;
}]]></programlisting>
<para>
The rules for determining the bean types of a producer field parallel the rules for producer methods.
</para>
<para>
A producer field is really just a shortcut that lets us avoid writing a useless getter method. However,
in addition to convenience, producer fields serve a specific purpose as an adaptor for Java EE component
environment injection, but to learn more about that, you'll have to wait until <xref linkend="resources"/>.
Because we can't wait to get to work on some examples.
</para>
</section>
</section>
<!--
<section id="bean-descriptor">
<title>The (minimal) bean descriptor</title>
<para>
First, it's important to understand that the XML bean descriptor in CDI (beans.xml) is not there to define
beans in XML, like in other popular bean containers. Rather, you use this file to enable CDI services for the
current bean archive that is difficult to define consistently in Java or which you don't want to define in Java
(e.g., to accomodate testing).
</para>
<para>
For example, the XML is used to enable interceptors (which are disabled by default) and define interceptor
ordering. So the bean descriptor <emphasis>complements</emphasis> the metadata that is provided in the Java
language syntax. (You may still want to define beans in XML for other reasons, but that is the concern of an
extension).
</para>
<para>
Let's first ask why the beans.xml is required, then look at what services it is used used to enable.
</para>
<section>
<title>Why is beans.xml required?</title>
<para>
You may be wondering, if beans are not described using XML, why do we need beans.xml at all, particularly if
you don't have anything that you would need the bean descriptor to enable (alternatives, interceptors or
decorators)?
</para>
<para>
There are two things about CDI that we need to keep in mind:
</para>
<itemizedlist>
<listitem>
<para>
CDI does not require any special declaration for a Java class to be injected - that's right, no
annotation or XML declaration at all!
</para>
</listitem>
<listitem>
<para>
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.
</para>
</listitem>
</itemizedlist>
<para>
The CDI specification calls the process of identifying beans in modules <emphasis>bean discovery</emphasis>.
</para>
<para>
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.
</para>
<para>
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.
</para>
<para>
So we have two choices. We could have the developer:
</para>
<orderedlist>
<listitem>
<para>explicitly exclude modules which do not contain beans, or</para>
</listitem>
<listitem>
<para>explicitly declare modules which do contain beans.</para>
</listitem>
</orderedlist>
<para>
It should be clear that the second option is a much better way to go. Thus, 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.
</para>
<para>
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:
</para>
<itemizedlist>
<listitem>
<para>a class-level annotation,</para>
</listitem>
<listitem>
<para>the package,</para>
</listitem>
<listitem>
<para>some type it implements or extends, or</para>
</listitem>
<listitem>
<para>some naming convention.</para>
</listitem>
</itemizedlist>
<para>
We've got the first option covered. Annotate a bean <literal>@Alternative</literal>, 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 <literal>ProcessAnnotatedType</literal> event
for that class).
</para>
<para>
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.
</para>
<para>
Enough theory, what elements are available in beans.xml?
</para>
</section>
<section>
<title>Bean descriptor schema</title>
<para>
If you don't need to activate any interceptors, decorators or alternatives (you just have plain beans that
you need to use in an archive), the beans.xml file can be <emphasis>empty</emphasis>. If you do have one
of these requirements, then you need to start popularing the descriptor.
</para>
<para>
The root element of a beans.xml file is <literal>beans</literal>, with the following <ulink
url="http://anonsvn.jboss.org/repos/weld/api/trunk/cdi/src/main/resources/beans.xsd">schema</ulink>:
</para>
<programlisting role="XML"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_1.xsd">
</beans>]]></programlisting>
<para>
The <literal>beans</literal> element can have one or more of each of the following children:
</para>
<itemizedlist>
<listitem>
<para><literal>interceptors</literal></para>
</listitem>
<listitem>
<para><literal>decorators</literal></para>
</listitem>
<listitem>
<para><literal>alternatives</literal></para>
</listitem>
</itemizedlist>
<para>
Let's look at each element in detail.
</para>
<section>
<title><interceptors></title>
<para>
By default, a bean archive has no enabled interceptors bound via interceptor bindings. An interceptor
must be explicitly enabled by listing the fully qualified class name in a child <class> element of
<interceptors>.
</para>
<para>
There may be zero or more interceptor class elements. The order of the class
declarations determines the interceptor ordering. Interceptors which occur earlier in the list are called
first. The same class may not be listed twice. And of course, the class must exist and it must be an
interceptor class.
</para>
<programlisting role="XML"><![CDATA[<interceptors>
<class>com.acme.intercept.SecurityInterceptor</class>
<class>com.acme.intercept.TransactionInterceptor</class>
</interceptors>]]></programlisting>
</section>
<section>
<title><decorators></title>
<para>
By default, a bean archive has no enabled decorators. A decorator
must be explicitly enabled by listing the fully qualified class name in a child <class> element of
<decorators>.
</para>
<para>
There may be zero or more decorator class elements. The order of the class
declarations determines the decorator ordering. Decorators which occur earlier in the list are called
first. The same class may not be listed twice. And of course, the class must exist and it must be an
decorator class.
</para>
<programlisting role="XML"><![CDATA[<interceptors>
<class>com.acme.decorate.BigAccountDecorator</class>
<class>com.acme.decorate.SpecialGiftDecorator</class>
</interceptors>]]></programlisting>
</section>
<section>
<title><alternatives></title>
<para>
An alternative is a bean that must be explicitly declared in the beans.xml file if it should be available
for lookup, injection or EL resolution. By default, a bean archive has no active alternatives. An
alternative must be explicitly declared using the fully qualified bean class name or stereotype class
name in either a child <class>
or <stereotype> element of <alternatives>, respectively.
</para>
<para>
An alternative is selected for the bean archive if either: the alternative is a managed bean or session
bean and the bean class of the bean is listed, or the alternative is a producer method, field or
resource, and the bean class that declares the method or field is listed, or any
<literal>@Alternative</literal> stereotype of the alternative is listed.
</para>
<para>
There may be zero or more alternative bean class elements. The same class may not be listed twice. And of
course, the class must exist and it must be an alternative bean class.
</para>
<para>
There may also be zero or more <literal>@Alternative</literal> stereotype elements. The same stereotype
may not be listed twice. And of course, the stereotype class must exist and it must be an stereotype
annotation.
</para>
<programlisting role="XML"><![CDATA[<stereotypes>
<class>com.acme.business.MockPaymentProcessor</class>
<stereotype>com.acme.stereotype.Mock</stereotype>
</stereotypes>]]></programlisting>
</section>
<para>
And that's it! A very simple schema, used only to activate and order CDI services.
</para>
</section>
</section>
-->
<!--
vim:et:ts=3:sw=3:tw=120
-->
</chapter>