Modified: websites/production/tapestry/content/tapestry-ioc-decorators.html
==============================================================================
--- websites/production/tapestry/content/tapestry-ioc-decorators.html (original)
+++ websites/production/tapestry/content/tapestry-ioc-decorators.html Sat Aug  
8 17:20:04 2015
@@ -31,8 +31,6 @@
   <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
   <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
   <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
   <script type="text/javascript">
   SyntaxHighlighter.defaults['toolbar'] = false;
   SyntaxHighlighter.all();
@@ -62,43 +60,13 @@
 <div class="clearer"></div>
 
   <div id="breadcrumbs">
-        <a href="index.html">Apache Tapestry</a>&nbsp;&gt;&nbsp;<a 
href="documentation.html">Documentation</a>&nbsp;&gt;&nbsp;<a 
href="user-guide.html">User Guide</a>&nbsp;&gt;&nbsp;<a 
href="ioc.html">IoC</a>&nbsp;&gt;&nbsp;<a 
href="tapestry-ioc-decorators.html">Tapestry IoC Decorators</a>
+        <a href="index.html">Apache Tapestry</a>&nbsp;&gt;&nbsp;<a 
href="documentation.html">Documentation</a>&nbsp;&gt;&nbsp;<a 
href="user-guide.html">User Guide</a>&nbsp;&gt;&nbsp;<a 
href="ioc.html">IOC</a>&nbsp;&gt;&nbsp;<a 
href="tapestry-ioc-decorators.html">Tapestry IoC Decorators</a>
     <a class="edit" title="Edit this page (requires approval -- just ask on 
the mailing list)" 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=23338481";>edit</a>
   </div>
 
 <div id="content">
-<div id="ConfluenceContent">
-
-<h1 id="TapestryIoCDecorators-TapestryIoCDecorators">Tapestry IoC 
Decorators</h1>
-
-<div class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body">
-<p>Starting with Tapestry 5.1, Service Decoration is augmented with <a 
shape="rect" href="service-advisors.html">Service Advice</a>. Advisors are  
similar but more general, as they work on any service interface, which doesn't 
have to be known at build time. Decoration is used when the type of the service 
being decorated <em>is</em> known at build time, and involves supplying a new 
implementation of the service interface.</p></div></div>
-
-<p><em>Decoration</em> is the name of a popular design pattern. Using 
decoration, an existing object's behavior can be extended without changing the 
implementation of the object.</p>
-
-<p>Instead, a new object is placed <em>around</em> the existing object. The 
rest of the world sees this new object, termed an <strong>interceptor</strong>. 
The interceptor implements the same interface as the underlying object being 
decorated.</p>
-
-<p>A common example for this is the Java I/O library. The abstract InputStream 
base class has a very simple API for reading bytes from a stream (and a few 
other things). Subclasses of InputStream provide a wide array of other options 
such as buffering, encryption or decryption, as well as control over the source 
of data read by the stream. All of these <em>concerns</em> are encapsulated in 
different implementations of InputStream, and all can be connected together in 
a kind of pipeline, using the common InputStream API.</p>
-
-<p>Tapestry IoC uses a similar approach, where one or more interceptor 
objects, all implementing the service interface, are strung together. The 
service's proxy (responsible for just-in-time instantiation of the service 
implementation) is at one end of this pipeline, the core service implementation 
is at the other.</p>
-
-<p>For each method in the service interface, the interceptor object can 
perform some operations before and after re-invoking the same method on the 
core service implementation. This is another design pattern: 
<em>delegation</em>. An interceptor can even catch exceptions thrown by the 
underlying implementation and react to them. A sufficiently clever interceptor 
could retry a method if an exception is thrown, or could "soften" a checked 
exception by wrapping it in a RuntimeException.</p>
-
-<p>Decorators often are used in the context of <em>cross-cutting 
concerns</em>, such as logging or transaction management. This approach is a 
kind of <em>aspect oriented design</em>.</p>
-
-<p>One such cross cutting concern is lazy initialization of services. In 
Apache HiveMind, services are created only as needed, when a method of a 
service interface is first invoked. This concern is supplied by the Tapestry 
IoC framework itself, but similar concerns are easily implemented as 
decorations.</p>
-
-<p>Whereas the popular AspectJ framework changes the compiled bytecode of your 
classes (it calls the process "weaving"), with Tapestry IoC, the approach is to 
wrap your existing classes in new objects. These wrapper objects are often 
dynamically created at runtime.</p>
-
-<p>It is also common to have <em>multiple</em> decorations on a single 
service. In this case, a whole stack of interceptor objects will be created, 
each delegating to the next. Tapestry IoC provides control over the order in 
which such decorations occur.</p>
-
-<p>Decorations are driven by service decoration methods. Often, a reusable 
service exists to do the grunt work of creating and instantiating a new 
class.</p>
-
-<h1 id="TapestryIoCDecorators-ServiceDecorationMethods">Service Decoration 
Methods</h1>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-package org.example.myapp.services;
+<div id="ConfluenceContent"><div class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Starting with Tapestry 5.1, 
Service Decoration is augmented with <a shape="rect" 
href="service-advisors.html">Service Advice</a>. Advisors are similar but more 
general, as they work on any service interface, which doesn't have to be known 
at build time. Decoration is used when the type of the service being decorated 
<em>is</em> known at build time, and involves supplying a new implementation of 
the service interface.</p></div></div><p><em>Decoration</em> is the name of a 
popular design pattern. Using decoration, an existing object's behavior can be 
extended without changing the implementation of the object.</p><p>Instead, a 
new object is placed <em>around</em> the existing object. The rest of the world 
sees this new object, terme
 d an <strong>interceptor</strong>. The interceptor implements the same 
interface as the underlying object being decorated.</p><p>A common example for 
this is the Java I/O library. The abstract InputStream base class has a very 
simple API for reading bytes from a stream (and a few other things). Subclasses 
of InputStream provide a wide array of other options such as buffering, 
encryption or decryption, as well as control over the source of data read by 
the stream. All of these <em>concerns</em> are encapsulated in different 
implementations of InputStream, and all can be connected together in a kind of 
pipeline, using the common InputStream API.</p><p>Tapestry IoC uses a similar 
approach, where one or more interceptor objects, all implementing the service 
interface, are strung together. The service's proxy (responsible for 
just-in-time instantiation of the service implementation) is at one end of this 
pipeline, the core service implementation is at the other.</p><p>For each 
method in 
 the service interface, the interceptor object can perform some operations 
before and after re-invoking the same method on the core service 
implementation. This is another design pattern: <em>delegation</em>. An 
interceptor can even catch exceptions thrown by the underlying implementation 
and react to them. A sufficiently clever interceptor could retry a method if an 
exception is thrown, or could "soften" a checked exception by wrapping it in a 
RuntimeException.</p><p>Decorators often are used in the context of 
<em>cross-cutting concerns</em>, such as logging or transaction management. 
This approach is a kind of <em>aspect oriented design</em>.</p><p>One such 
cross cutting concern is lazy initialization of services. In Apache HiveMind, 
services are created only as needed, when a method of a service interface is 
first invoked. This concern is supplied by the Tapestry IoC framework itself, 
but similar concerns are easily implemented as decorations.</p><p>Whereas the 
popular AspectJ fra
 mework changes the compiled bytecode of your classes (it calls the process 
"weaving"), with Tapestry IoC, the approach is to wrap your existing classes in 
new objects. These wrapper objects are often dynamically created at 
runtime.</p><p>It is also common to have <em>multiple</em> decorations on a 
single service. In this case, a whole stack of interceptor objects will be 
created, each delegating to the next. Tapestry IoC provides control over the 
order in which such decorations occur.</p><p>Decorations are driven by service 
decoration methods. Often, a reusable service exists to do the grunt work of 
creating and instantiating a new class.</p><h1 
id="TapestryIoCDecorators-ServiceDecorationMethods">Service Decoration 
Methods</h1><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.services.LoggingDecorator;
 import org.slf4j.Logger;
@@ -118,35 +86,13 @@ public class MyAppModule
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }
 }</pre>
-</div></div>
-
-<p>The method decorateIndexer() is a service decorator method because it 
starts with the word "decorate". In this simple case, only the myapp.Indexer 
service will be decorated, even if there are other services in this module or 
others ... this is because of the name match ("decorateIndexer" and 
"buildIndexer"), but we'll shortly see how annotations can be used to target 
many services for decoration.</p>
-
-<p>We are using the parameterized types here (the &lt;T&gt;), to reinforce the 
fact that the delegate object passed in (which will be the core service 
implementation, or some other interceptor) must implement the service 
interface, and that the decorator method must return an instance of the service 
interface.</p>
-
-<p>The values that may be provided to a decorator method are exactly the same 
as for a builder method, with one addition: The underlying service will be 
passed in as a parameter of type java.lang.Object (after type erasure, the 
<code>T delegate</code> parameter becomes <code>Object delegate</code>).</p>
-
-<p>In the above example, the decorator method receives the core service 
implementation, the service interface for the Indexer service, the Log for the 
Indexer service, and an interceptor factory that generates logging 
interceptors.</p>
-
-<p>The "heavy lifting" is provided by the factory, which will create a new 
interceptor that logs method entry before delegating to the core service 
implementation. The interceptor will also log method parameters, return values, 
and even log exceptions.</p>
-
-<p>The return value of the method is the new interceptor. You may return null 
if your decorator method decides not to decorate the supplied service.</p>
-
-<p>Alternately, when targetting services whose type is known at compile time, 
you may provide a parameter whose type matches the service interface. For 
example, decorateIndexer() will always be applied to the Indexer service, whose 
type (Indexer) is known. We could therefore rewrite decorateIndexer() as:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-  public static Indexer decorateIndexer(Indexer delegate, Logger logger, 
LoggingDecorator decorator)
+</div></div><p>The method decorateIndexer() is a service decorator method 
because it starts with the word "decorate". In this simple case, only the 
myapp.Indexer service will be decorated, even if there are other services in 
this module or others ... this is because of the name match ("decorateIndexer" 
and "buildIndexer"), but we'll shortly see how annotations can be used to 
target many services for decoration.</p><p>We are using the parameterized types 
here (the &lt;T&gt;), to reinforce the fact that the delegate object passed in 
(which will be the core service implementation, or some other interceptor) must 
implement the service interface, and that the decorator method must return an 
instance of the service interface.</p><p>The values that may be provided to a 
decorator method are exactly the same as for a builder method, with one 
addition: The underlying service will be passed in as a parameter of type 
java.lang.Object (after type erasure, the <code>T delegate</code> parameter be
 comes <code>Object delegate</code>).</p><p>In the above example, the decorator 
method receives the core service implementation, the service interface for the 
Indexer service, the Log for the Indexer service, and an interceptor factory 
that generates logging interceptors.</p><p>The "heavy lifting" is provided by 
the factory, which will create a new interceptor that logs method entry before 
delegating to the core service implementation. The interceptor will also log 
method parameters, return values, and even log exceptions.</p><p>The return 
value of the method is the new interceptor. You may return null if your 
decorator method decides not to decorate the supplied 
service.</p><p>Alternately, when targetting services whose type is known at 
compile time, you may provide a parameter whose type matches the service 
interface. For example, decorateIndexer() will always be applied to the Indexer 
service, whose type (Indexer) is known. We could therefore rewrite 
decorateIndexer() as:</p><div 
 class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  public static Indexer decorateIndexer(Indexer 
delegate, Logger logger, LoggingDecorator decorator)
   {
     return decorator.build(Indexer.class, delegate, "Indexer", logger);
   }</pre>
-</div></div>
-
-<p>Of course, nothing stops you from combining building with decorating inside 
the service builder method:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-package org.example.myapp.services;
+</div></div><p>Of course, nothing stops you from combining building with 
decorating inside the service builder method:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.services.LoggingDecorator;
 import org.slf4j.Logger;
@@ -158,54 +104,16 @@ public class MyAppModule
     return decorator.build(Indexer.class, logger, new IndexerImpl());
   }
 }</pre>
-</div></div>
-
-<p>But as we'll see next, it's possible to have a single decorator method work 
on many different services by using annotations.</p>
-
-<h1 id="TapestryIoCDecorators-TargetingMultipleServices">Targeting Multiple 
Services</h1>
-
-<p>By using the @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Match.html";>Match</a>
 annotation, you may identify which services are to be decorated.</p>
-
-<p>The value specified in the Match annotation is one or more patterns. These 
patterns are used to match services. Patterns take two forms: glob patterns and 
regular expressions.</p>
-
-<p>In a glob pattern, a "*" at the start or end of a string will match zero or 
more characters. Regular expressions provide a lot more matching power, but 
require a more involved syntax.</p>
-
-<p>In either case, the matching is case insensitive.</p>
-
-<p>For example, to target all the services in your module:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-  @Match("*")
+</div></div><p>But as we'll see next, it's possible to have a single decorator 
method work on many different services by using annotations.</p><h1 
id="TapestryIoCDecorators-TargetingMultipleServices">Targeting Multiple 
Services</h1><p>By using the @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Match.html";>Match</a>
 annotation, you may identify which services are to be decorated.</p><p>The 
value specified in the Match annotation is one or more patterns. These patterns 
are used to match services. Patterns take two forms: glob patterns and regular 
expressions.</p><p>In a glob pattern, a "*" at the start or end of a string 
will match zero or more characters. Regular expressions provide a lot more 
matching power, but require a more involved syntax.</p><p>In either case, the 
matching is case insensitive.</p><p>For example, to target all the services in 
your module:</p><div class="code panel pdl" style="border-wi
 dth: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Match("*")
   public static &lt;T&gt; T decorateLogging(Class&lt;T&gt; serviceInterface, T 
delegate,
     String serviceId, Logger logger,
     LoggingDecorator decorator)
   {
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }   </pre>
-</div></div>
-
-<p>You can use multiple patterns with @Match, in which case, the decorator 
will be applied to a service that matches <em>any</em> of the patterns. For 
instance, if you only wanted logging for your data access and business logic 
services, you might end up with <code>@Match("Data*", "*Logic")</code> (based, 
of course, on how you name your services).</p>
-
-<p>As the preceding example showed, a simple "glob" matching is supported, 
where a asterisk ('*') may be used at the start or end of the match string to 
match any number of characters. As elsewhere, matching is case insensitive.</p>
-
-<p>Thus, <code>@Match("*")</code> is dangerous, because it will match every 
service in every module.</p>
-
-<p><em>Note: It is not possible to decorate the services of the 
TapestryIOCModule.</em></p>
-
-<p><em>Note: Another idea will be other ways of matching services: base on 
inheritance of the service interface and/or based on the presence of particular 
class annotations on the service interface. None of this has been implemented 
yet, and can readily be accomplished inside the decorator method (which will 
return null if it decides the service doesn't need decoration).</em></p>
-
-<h1 id="TapestryIoCDecorators-OrderingofDecorators">Ordering of Decorators</h1>
-
-<p>In cases where multiple decorators will apply to a single service, you can 
control the order in which decorators are applied using an additional 
annotation: @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Order.html";>Order</a>.</p>
-
-<p>This annotation allows any number of <a shape="rect" 
href="ordering-by-constraints.html">ordering constraints</a> to be specified 
for the decorator, to order it relative to any other decorators.</p>
-
-<p>For example, you almost always want logging decorators to come first, 
so:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-  @Match("*")
+</div></div><p>You can use multiple patterns with @Match, in which case, the 
decorator will be applied to a service that matches <em>any</em> of the 
patterns. For instance, if you only wanted logging for your data access and 
business logic services, you might end up with <code>@Match("Data*", 
"*Logic")</code> (based, of course, on how you name your services).</p><p>As 
the preceding example showed, a simple "glob" matching is supported, where a 
asterisk ('*') may be used at the start or end of the match string to match any 
number of characters. As elsewhere, matching is case insensitive.</p><p>Thus, 
<code>@Match("*")</code> is dangerous, because it will match every service in 
every module.</p><p><em>Note: It is not possible to decorate the services of 
the TapestryIOCModule.</em></p><p><em>Note: Another idea will be other ways of 
matching services: base on inheritance of the service interface and/or based on 
the presence of particular class annotations on the service interface. None o
 f this has been implemented yet, and can readily be accomplished inside the 
decorator method (which will return null if it decides the service doesn't need 
decoration).</em></p><h1 
id="TapestryIoCDecorators-OrderingofDecorators">Ordering of 
Decorators</h1><p>In cases where multiple decorators will apply to a single 
service, you can control the order in which decorators are applied using an 
additional annotation: @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Order.html";>Order</a>.</p><p>This
 annotation allows any number of <a shape="rect" 
href="ordering-by-constraints.html">ordering constraints</a> to be specified 
for the decorator, to order it relative to any other decorators.</p><p>For 
example, you almost always want logging decorators to come first, so:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Match("*")
   @Order("before:*")
   public static &lt;T&gt; T decorateLogging(Class&lt;T&gt; serviceInterface, T 
delegate,
     String serviceId, Logger logger,
@@ -213,28 +121,13 @@ public class MyAppModule
   {
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }   </pre>
-</div></div>
-
-<p>"before:*" indicates that this decorator should come before any decorator 
in <em>any</em> module.</p>
-
-<p><strong>Note:</strong> the ordering of decorators is in terms of the 
<em>effect</em> desired. Internally, the decorators are invoked last to first 
(since each once receives the "next" interceptor as its delegate). So the core 
service implementation is created (via a service builder method) and that is 
passed to the last decorator method. The interceptor created there is passed to 
the the next-to-last decorator method, and so forth.</p>
-
-<p>It should now be evident that the delegate passed into a decorator method 
is sometimes the core service implementation, and some times an interceptor 
object created by some other decorator method.</p>
+</div></div><p>"before:*" indicates that this decorator should come before any 
decorator in <em>any</em> module.</p><p><strong>Note:</strong> the ordering of 
decorators is in terms of the <em>effect</em> desired. Internally, the 
decorators are invoked last to first (since each once receives the "next" 
interceptor as its delegate). So the core service implementation is created 
(via a service builder method) and that is passed to the last decorator method. 
The interceptor created there is passed to the the next-to-last decorator 
method, and so forth.</p><p>It should now be evident that the delegate passed 
into a decorator method is sometimes the core service implementation, and some 
times an interceptor object created by some other decorator method.</p><h1 
id="TapestryIoCDecorators-Annotationdrivendecorators">Annotation driven 
decorators</h1><p>
 
-<h1 id="TapestryIoCDecorators-Annotationdrivendecorators">Annotation driven 
decorators</h1>
-
-
-
-<div class="confluence-information-macro 
confluence-information-macro-information"><p class="title">Added in 
5.2</p><span class="aui-icon aui-icon-small aui-iconfont-info 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body">
+</p><div class="confluence-information-macro 
confluence-information-macro-information"><p class="title">Added in 
5.2</p><span class="aui-icon aui-icon-small aui-iconfont-info 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body">
 </div></div>
 <div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;">
-</div>
-
-<p>Starting from version 5.2, Tapestry supports annotation-driven decorator 
methods. If the <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Decorate.html";>@Decorate</a>
 annotation is present, the decorator method can be arbitrary named, as shown 
in the following example.</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-  @Decorate
+<p>&#160;</p></div>Starting from version 5.2, Tapestry supports 
annotation-driven decorator methods. If the <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Decorate.html";>@Decorate</a>
 annotation is present, the decorator method can be arbitrary named, as shown 
in the following example.<div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Decorate
   @Match("*DAO")
   public static &lt;T&gt; T byServiceId(Class&lt;T&gt; serviceInterface, T 
delegate,
     String serviceId, Logger logger,
@@ -243,15 +136,8 @@ public class MyAppModule
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }
 </pre>
-</div></div>
-
-<p>The decorator above is applied to any service whose id matches the "*DAO" 
pattern.</p>
-
-<p>Alternatively, marker annotations can be placed on the decorate method to 
match a specific service.</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-  @Decorate
+</div></div><p>The decorator above is applied to any service whose id matches 
the "*DAO" pattern.</p><p>Alternatively, marker annotations can be placed on 
the decorate method to match a specific service.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Decorate
   @Blue
   public static &lt;T&gt; T byMarkerAnnotation(Class&lt;T&gt; 
serviceInterface, T delegate,
     String serviceId, Logger logger,
@@ -260,15 +146,8 @@ public class MyAppModule
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }
 </pre>
-</div></div>
-
-<p>The decorator above is applied to any service that is marked by the @Blue 
annotation.</p>
-
-<p>By default, <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Decorate.html";>@Decorate</a>
 annotation applies the decorator to any service matched by the <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Match.html";>@Match</a>
 or marker annotations. You can limit the matching to a single service 
interface, as shown in the following example.</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-  @Decorate(serviceInterface=MyService.class)
+</div></div><p>The decorator above is applied to any service that is marked by 
the @Blue annotation.</p><p>By default, <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Decorate.html";>@Decorate</a>
 annotation applies the decorator to any service matched by the <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Match.html";>@Match</a>
 or marker annotations. You can limit the matching to a single service 
interface, as shown in the following example.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Decorate(serviceInterface=MyService.class)
   @Match("*DAO")
   public static &lt;T&gt; T byServiceId(Class&lt;T&gt; serviceInterface, T 
delegate,
     String serviceId, Logger logger,
@@ -276,13 +155,8 @@ public class MyAppModule
   {
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }</pre>
-</div></div>
-
-<p>In the example above, the decorator is applied to any implementation of 
MyService interfaces whose id matches the "*DAO" pattern.</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-  @Decorate(serviceInterface=MyService.class)
+</div></div><p>In the example above, the decorator is applied to any 
implementation of MyService interfaces whose id matches the "*DAO" 
pattern.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Decorate(serviceInterface=MyService.class)
   @Blue
   public static &lt;T&gt; T byMarkerAnnotation(Class&lt;T&gt; 
serviceInterface, T delegate,
     String serviceId, Logger logger,
@@ -291,35 +165,8 @@ public class MyAppModule
     return decorator.build(serviceInterface, delegate, serviceId, logger);
   }
 </pre>
-</div></div>
-
-<p>The decorator above is applied to any implementation of the MyService 
interface that is marked by the @Blue annotation.</p>
-
-<h1 id="TapestryIoCDecorators-CreatingyourownDecorators">Creating your own 
Decorators</h1>
-
-<p>Decorators are a limited form of Aspect Oriented Programming, so we have 
borrowed some of that terminology here.</p>
-
-<p>A decorator exists to create an <em>interceptor</em>. The interceptor wraps 
around the service (because these interceptors can get chained, we talk about 
the "delegate" and not the "service").</p>
-
-<p>Each method of the interceptor will take <em>advice</em>. Advice is 
provided by a <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/MethodAdvice.html";>MethodAdvice</a>
 instance. The sole method, <code>advise()</code>, receives an <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/Invocation.html";>Invocation</a>.
 MethodAdvice gives you a chance to see what the method invocation <em>is</em>; 
you can query the name of the method, and the types and values of the 
parameters.</p>
-
-<p>The MethodAdvice can override the parameters if necessary, then invoke 
<code>proceed()</code>. This call invokes the corresponding method on the 
original object, the delegate.</p>
-
-<p>If the method call throws a runtime exception, that exception is not 
caught. Your method advice can put a try ... catch block around the call to 
proceed() if interested in catching runtime exceptions.</p>
-
-<p>Checked exceptions are not thrown (since they are not part of the proceed() 
method's signature). Instead the invocation's <code>isFail()</code> method will 
return true. You can then retrieve the exception or override it.</p>
-
-<p>In the normal success case, you can ask for the return value and even 
override it before returning from the advise() method.</p>
-
-<p>In other words, you have total control. Your MethodAdvice can query or 
change parameters, decide whether it proceed into the original code, it can 
intercept exceptions that are thrown and replace them, and can query or even 
replace the return value.</p>
-
-<p>The <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/AspectDecorator.html";>AspectDecorator</a>
 service is how you put your MethodAdvice into action.</p>
-
-<p>By way of an example, we'll show an implementation of the LoggingDecorator 
service:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-public class LoggingDecoratorImpl implements LoggingDecorator
+</div></div><p>The decorator above is applied to any implementation of the 
MyService interface that is marked by the @Blue annotation.</p><h1 
id="TapestryIoCDecorators-CreatingyourownDecorators">Creating your own 
Decorators</h1><p>Decorators are a limited form of Aspect Oriented Programming, 
so we have borrowed some of that terminology here.</p><p>A decorator exists to 
create an <em>interceptor</em>. The interceptor wraps around the service 
(because these interceptors can get chained, we talk about the "delegate" and 
not the "service").</p><p>Each method of the interceptor will take 
<em>advice</em>. Advice is provided by a <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/MethodAdvice.html";>MethodAdvice</a>
 instance. The sole method, <code>advise()</code>, receives an <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/Invocation.html";>Invocation</a>.
 MethodAdvic
 e gives you a chance to see what the method invocation <em>is</em>; you can 
query the name of the method, and the types and values of the 
parameters.</p><p>The MethodAdvice can override the parameters if necessary, 
then invoke <code>proceed()</code>. This call invokes the corresponding method 
on the original object, the delegate.</p><p>If the method call throws a runtime 
exception, that exception is not caught. Your method advice can put a try ... 
catch block around the call to proceed() if interested in catching runtime 
exceptions.</p><p>Checked exceptions are not thrown (since they are not part of 
the proceed() method's signature). Instead the invocation's 
<code>isFail()</code> method will return true. You can then retrieve the 
exception or override it.</p><p>In the normal success case, you can ask for the 
return value and even override it before returning from the advise() 
method.</p><p>In other words, you have total control. Your MethodAdvice can 
query or change parameters, deci
 de whether it proceed into the original code, it can intercept exceptions that 
are thrown and replace them, and can query or even replace the return 
value.</p><p>The <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/AspectDecorator.html";>AspectDecorator</a>
 service is how you put your MethodAdvice into action.</p><p>By way of an 
example, we'll show an implementation of the LoggingDecorator service:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class LoggingDecoratorImpl implements 
LoggingDecorator
 {
     private final AspectDecorator aspectDecorator;
 
@@ -374,18 +221,7 @@ public class LoggingDecoratorImpl implem
                                                     
serviceInterface.getName()));
     }
 }</pre>
-</div></div>
-
-<p><em>The actual code has been refactored slightly since this documentation 
was written.</em></p>
-
-<p>Most of the logging logic occurs inside the ServiceLogger object, the 
MethodAdvice exists to call the right methods at the right time. A Logger 
doesn't <em>change</em> parameter values (or thrown exceptions, or the result), 
it just captures and logs the data.</p>
-
-<p>Notice that for runtime exceptions, we catch the exception, log it, and 
rethrow it.</p>
-
-<p>For checked exceptions, we use isFail() and getThrown().</p>
-
-<p>The AspectDecorator service can also be used in more complicated ways: it 
is possible to only advise some of the methods and not others, or use different 
advice for different methods. Check the JavaDoc for more details.</p>
-</div>
+</div></div><p><em>The actual code has been refactored slightly since this 
documentation was written.</em></p><p>Most of the logging logic occurs inside 
the ServiceLogger object, the MethodAdvice exists to call the right methods at 
the right time. A Logger doesn't <em>change</em> parameter values (or thrown 
exceptions, or the result), it just captures and logs the data.</p><p>Notice 
that for runtime exceptions, we catch the exception, log it, and rethrow 
it.</p><p>For checked exceptions, we use isFail() and getThrown().</p><p>The 
AspectDecorator service can also be used in more complicated ways: it is 
possible to only advise some of the methods and not others, or use different 
advice for different methods. Check the JavaDoc for more 
details.</p><p>&#160;</p><p></p></div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/tapestry-ioc-modules.html
==============================================================================
--- websites/production/tapestry/content/tapestry-ioc-modules.html (original)
+++ websites/production/tapestry/content/tapestry-ioc-modules.html Sat Aug  8 
17:20:04 2015
@@ -31,8 +31,6 @@
   <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
   <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
   <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
   <script type="text/javascript">
   SyntaxHighlighter.defaults['toolbar'] = false;
   SyntaxHighlighter.all();
@@ -62,35 +60,13 @@
 <div class="clearer"></div>
 
   <div id="breadcrumbs">
-        <a href="index.html">Apache Tapestry</a>&nbsp;&gt;&nbsp;<a 
href="documentation.html">Documentation</a>&nbsp;&gt;&nbsp;<a 
href="user-guide.html">User Guide</a>&nbsp;&gt;&nbsp;<a 
href="ioc.html">IoC</a>&nbsp;&gt;&nbsp;<a 
href="tapestry-ioc-modules.html">Tapestry IoC Modules</a>
+        <a href="index.html">Apache Tapestry</a>&nbsp;&gt;&nbsp;<a 
href="documentation.html">Documentation</a>&nbsp;&gt;&nbsp;<a 
href="user-guide.html">User Guide</a>&nbsp;&gt;&nbsp;<a 
href="ioc.html">IOC</a>&nbsp;&gt;&nbsp;<a 
href="tapestry-ioc-modules.html">Tapestry IoC Modules</a>
     <a class="edit" title="Edit this page (requires approval -- just ask on 
the mailing list)" 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=23338484";>edit</a>
   </div>
 
 <div id="content">
-<div id="ConfluenceContent">
-
-<h1 id="TapestryIoCModules-TapestryIoCModules">Tapestry IoC Modules</h1>
-
-<p>You inform Tapestry about your services and contributions by providing a 
module class.</p>
-
-<p>The module class is a plain Java class. A system of annotations and naming 
conventions allow Tapestry to determine what services are provided by the 
module.</p>
-
-<p>A module class exists for the following reasons:</p>
-
-<ul><li>To <em>bind</em> service interfaces to service 
implementations</li><li>To contribute configuration data <em>into</em> 
services</li><li>To <em>decorate</em> services by providing 
<em>interceptors</em> around them</li><li>To provide explicit code for building 
a service</li><li>To set a default <em>marker</em> for all services defined in 
the module</li></ul>
-
-
-<p>All public methods of a module class must be meaningful to Tapestry (be one 
of the categories above). Any extra public methods result in startup exceptions 
(because the method may contain a typo).</p>
-
-<h1 id="TapestryIoCModules-ServiceBuilderMethods">Service Builder Methods</h1>
-
-<p>Service builder methods were the original way to define a service and 
provide the logic to construct it; although this is now more commonly (and 
succinctly) accomplished using the bind() method, there are still many cases 
where service builder methods are useful.</p>
-
-<p>Service builder methods are public methods. They are often static. Here's a 
trivial example:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-package org.example.myapp.services;
+<div id="ConfluenceContent"><p>You inform Tapestry about your services and 
contributions by providing a <strong>module</strong> class.</p><p>The module 
class is a plain Java class that you create to inform Tapestry about your 
services and contributions.</p><p>A system of annotations and naming 
conventions allow Tapestry to determine what services are provided by the 
module.</p><p>A module class exists for the following reasons:</p><ul><li>To 
<em>bind</em> service interfaces to service implementations</li><li>To 
contribute configuration data <em>into</em> services</li><li>To 
<em>decorate</em> services by providing <em>interceptors</em> around 
them</li><li>To provide explicit code for building a service</li><li>To set a 
default <em>marker</em> for all services defined in the module</li></ul><p>All 
public methods of a module class must be meaningful to Tapestry (be one of the 
categories above). Any extra public methods result in startup exceptions 
(because the method may contain a typo
 ).</p><h1 id="TapestryIoCModules-ServiceBuilderMethods">Service Builder 
Methods</h1><p>Service builder methods were the original way to define a 
service and provide the logic to construct it; although this is now more 
commonly (and succinctly) accomplished using the bind() method, there are still 
many cases where service builder methods are useful.</p><p>Service builder 
methods are public methods. They are often static. Here's a trivial 
example:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package org.example.myapp.services;
 
 public class MyAppModule
 {
@@ -99,31 +75,8 @@ public class MyAppModule
     return new IndexerImpl();
   }
 }</pre>
-</div></div>
-
-<p>Any public method (static or instance) whose name starts with "build" is a 
service builder method, implicitly defining a service within the module.</p>
-
-<p>Here we're defining a service around the Indexer service interface 
(presumably also in the org.example.myapp.services package).</p>
-
-<p>Every service has a unique id, used to identify it throughout the Registry 
of services (the Registry is the combined sum of all services from all 
modules). If you don't provide an explicit service id, as in this example, the 
service id is drawn from the return type; this service has an id of 
"Indexer".</p>
-
-<p>You can give a service an explicit id by adding it to the method name: 
buildIndexer(). This is useful when you do not want the service id to match the 
service interface name (for example, when you have different services that 
implement the same interface), or when you need to avoid name collisions on the 
method name (Java allows only a single method with a given name and set of 
parameters, even if the return types are different, so if you have two 
different service builder methods that take the same parameters, you should 
give them explicit service ids in the method name).</p>
-
-<p>Tapestry IoC is <a shape="rect" href="case-insensitivity.html">case 
insensitive</a>; later we can refer to this service as "indexer" or "INDEXER" 
or any variation thereof, and connect to this service.</p>
-
-<p>Service ids must be unique; if another module contributes a service with 
the id "Indexer" (or any case variation thereof) a runtime exception will occur 
when the Registry is created.</p>
-
-<p>We could extend this example by adding additional service builder methods, 
or by showing how to inject dependencies. See <a shape="rect" 
href="defining-tapestry-ioc-services.html">the service documentation</a> for 
more details.</p>
-
-<h1 id="TapestryIoCModules-AutobuildingServices">Autobuilding Services</h1>
-
-<p>Main article: <a shape="rect" 
href="defining-tapestry-ioc-services.html">Defining Tapestry IOC 
Services</a></p>
-
-<p>An alternate, and usually preferred, way to define a service is via a 
module's bind() method. The previous example can be rewritten as:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-package org.example.myapp.services;
+</div></div><p>Any public method (static or instance) whose name starts with 
"build" is a service builder method, implicitly defining a service within the 
module.</p><p>Here we're defining a service around the Indexer service 
interface (presumably also in the org.example.myapp.services 
package).</p><p>Every service has a unique id, used to identify it throughout 
the Registry of services (the Registry is the combined sum of all services from 
all modules). If you don't provide an explicit service id, as in this example, 
the service id is drawn from the return type; this service has an id of 
"Indexer".</p><p>You can give a service an explicit id by adding it to the 
method name: buildIndexer(). This is useful when you do not want the service id 
to match the service interface name (for example, when you have different 
services that implement the same interface), or when you need to avoid name 
collisions on the method name (Java allows only a single method with a given 
name and set of par
 ameters, even if the return types are different, so if you have two different 
service builder methods that take the same parameters, you should give them 
explicit service ids in the method name).</p><p>Tapestry IoC is <a shape="rect" 
href="case-insensitivity.html">case insensitive</a>; later we can refer to this 
service as "indexer" or "INDEXER" or any variation thereof, and connect to this 
service.</p><p>Service ids must be unique; if another module contributes a 
service with the id "Indexer" (or any case variation thereof) a runtime 
exception will occur when the Registry is created.</p><p>We could extend this 
example by adding additional service builder methods, or by showing how to 
inject dependencies. See <a shape="rect" 
href="defining-tapestry-ioc-services.html">the service documentation</a> for 
more details.</p><h1 id="TapestryIoCModules-AutobuildingServices">Autobuilding 
Services</h1><p>Main article: <a shape="rect" 
href="defining-tapestry-ioc-services.html">Defining Tapestry
  IOC Services</a></p><p>An alternate, and usually preferred, way to define a 
service is via a module's bind() method. The previous example can be rewritten 
as:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package org.example.myapp.services;
 
 import org.apache.tapestry5.ioc.ServiceBinder;
 
@@ -134,27 +87,8 @@ public class MyAppModule
      binder.bind(Indexer.class, IndexerImpl.class);
   }
 }</pre>
-</div></div>
-
-<p>For more details, see see <a shape="rect" 
href="defining-tapestry-ioc-services.html">Defining Tapestry IOC Services</a>. 
In most cases, autobuilding is the <em>preferred</em> approach.</p>
-
-<p>Generally speaking, you should always bind and autobuild your services. The 
only exceptions are when:</p>
-
-<ul><li>You wish to do more than just instantiate a class; for example, to 
register the class as an event listener with some other service.</li><li>There 
is <em>no implementation class</em>; in some cases, you can create your 
implementation on the fly using JDK dynamic proxies or bytecode 
generation.</li></ul>
-
-
-<p>The bind() method must be static; an exception is thrown if the bind() 
method exists but is an instance method.</p>
-
-<h1 id="TapestryIoCModules-Cacheing_ServicesCachingServices"><span 
class="confluence-anchor-link" 
id="TapestryIoCModules-Cacheing_Services"></span>Caching Services</h1>
-
-<p>You will occasionally find yourself in the position of injecting the same 
services into your service builder or service decorator methods repeatedly 
(this occurs much less often since the introduction of service autobuilding). 
This can result in quite a bit of redundant typing. Less code is better code, 
so as an alternative, you may define a <em>constructor</em> for your module 
that accepts annotated parameters (as with <a shape="rect" 
href="defining-tapestry-ioc-services.html">service builder injection</a>).</p>
-
-<p>This gives you a chance to store common services in instance variables for 
later use inside service builder methods.</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-
-public class MyModule
+</div></div><p>For more details, see see <a shape="rect" 
href="defining-tapestry-ioc-services.html">Defining Tapestry IOC Services</a>. 
In most cases, autobuilding is the <em>preferred</em> approach.</p><p>Generally 
speaking, you should always bind and autobuild your services. The only 
exceptions are when:</p><ul><li>You wish to do more than just instantiate a 
class; for example, to register the class as an event listener with some other 
service.</li><li>There is <em>no implementation class</em>; in some cases, you 
can create your implementation on the fly using JDK dynamic proxies or bytecode 
generation.</li></ul><p>The bind() method must be static; an exception is 
thrown if the bind() method exists but is an instance method.</p><h1 
id="TapestryIoCModules-Cacheing_ServicesCachingServices"><span 
class="confluence-anchor-link" 
id="TapestryIoCModules-Cacheing_Services"></span>Caching Services</h1><p>You 
will occasionally find yourself in the position of injecting the same services 
int
 o your service builder or service decorator methods repeatedly (this occurs 
much less often since the introduction of service autobuilding). This can 
result in quite a bit of redundant typing. Less code is better code, so as an 
alternative, you may define a <em>constructor</em> for your module that accepts 
annotated parameters (as with <a shape="rect" 
href="defining-tapestry-ioc-services.html">service builder 
injection</a>).</p><p>This gives you a chance to store common services in 
instance variables for later use inside service builder methods.</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class MyModule
 {   
   private final JobScheduler scheduler;
   private final FileSystem fileSystem;
@@ -174,55 +108,13 @@ public class MyModule
     return indexer;
   }
 }</pre>
-</div></div>
-
-<p>Notice that we've switched from <em>static</em> methods to 
<em>instance</em> methods. Since the builder methods are not static, the 
MyModule class will be instantiated so that the methods may be invoked. The 
constructor receives two common dependencies, which are stored into instance 
fields that may later be used inside service builder methods such as 
buildIndexer().</p>
-
-<p>This approach is far from required; all the builder methods of your module 
can be static if you wish. It is used when you have many common dependencies 
and wish to avoid defining those dependencies as parameters to multiple 
methods.</p>
-
-<p>Tapestry IoC automatically resolves the parameter type (JobScheduler and 
FileSystem, in the example) to the corresponding services that implement that 
type. When there's more than one service that implements the service interface, 
you'll get an error (but additional annotations and configuration can be used 
to ensure the correct service injected).</p>
-
-<p>For modules, there are two additional parameter types that are used to 
refer to <em>resources</em> that can be provided to the module instance (rather 
than <em>services</em> which may be injected).</p>
-
-<ul><li><a shape="rect" class="external-link" 
href="http://www.slf4j.org/api/org/slf4j/Logger.html"; >org.slf4j.Logger</a>: 
logger for the module (derived from the module's class name)</li><li><a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ObjectLocator.html";>ObjectLocator</a>:
 access to other services<br clear="none">
-Note that the fields are final: this is important. Tapestry IoC is thread-safe 
and you largely never have to think about concurrency issues. But in a busy 
application, different services may be built by different threads 
simultaneously. Each module class is a singleton, instantiated at most once, 
and making these fields final ensures that the values are available across 
multiple threads. Refer to Brian Goetz's <a shape="rect" class="external-link" 
href="http://www.javaconcurrencyinpractice.com/"; >Java Concurrency in 
Practice</a> for a more complete explanation of the relationship between final 
fields, constructors, and threads ... or just trust us!</li></ul>
-
-
-<p>Care should be taken with this approach: in some circumstances, you may 
force a situation in which the module constructor is dependent on itself. For 
example, if you invoke a method on any injected services defined within the 
same module from the module class' constructor, then the service implementation 
will be needed. Creating service implementations requires the module builder 
instance ... that's a recursive reference.</p>
-
-<p>Tapestry detects these scenarios and throws a runtime exception to prevent 
an endless loop.</p>
-
-<h1 id="TapestryIoCModules-ModuleClassImplementationNotes">Module Class 
Implementation Notes</h1>
-
-<p>Module classes are designed to be very, very simple to implement.</p>
-
-<p>Again, keep the methods very simple. Use <a shape="rect" 
href="defining-tapestry-ioc-services.html">parameter injection</a> to gain 
access to the dependencies you need.</p>
-
-<p>Be careful about inheritance. Tapestry will see all <em>public</em> 
methods, even those inherited from base classes. Tapestry <em>only</em> sees 
public methods.</p>
-
-<p>By convention, module class names end in Module and are final classes.</p>
-
-<p>You don't <em>have</em> to define your methods as static. The use of static 
methods is only absolutely necessary in a few cases, where the constructor for 
a module is dependent on contributions from the same module (this creates a 
chicken-and-the-egg situation that is resolved through static methods).</p>
-
-<h1 id="TapestryIoCModules-DefaultMarker">Default Marker</h1>
-
-<p>Services are often referenced by a particular marker interface on the 
method or constructor parameter. Tapestry will use the intersection of services 
with that exact marker and assignable by type to find a unique service to 
inject.</p>
-
-<p>Often, all services in a module should share a marker, this can be 
specified with a @Marker annotation on the module class. For example, the 
TapestryIOCModule:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-@Marker(Builtin.class)
+</div></div><p>Notice that we've switched from <em>static</em> methods to 
<em>instance</em> methods. Since the builder methods are not static, the 
MyModule class will be instantiated so that the methods may be invoked. The 
constructor receives two common dependencies, which are stored into instance 
fields that may later be used inside service builder methods such as 
buildIndexer().</p><p>This approach is far from required; all the builder 
methods of your module can be static if you wish. It is used when you have many 
common dependencies and wish to avoid defining those dependencies as parameters 
to multiple methods.</p><p>Tapestry IoC automatically resolves the parameter 
type (JobScheduler and FileSystem, in the example) to the corresponding 
services that implement that type. When there's more than one service that 
implements the service interface, you'll get an error (but additional 
annotations and configuration can be used to ensure the correct service 
injected).</p><p>For modules
 , there are two additional parameter types that are used to refer to 
<em>resources</em> that can be provided to the module instance (rather than 
<em>services</em> which may be injected).</p><ul><li><a shape="rect" 
class="external-link" href="http://www.slf4j.org/api/org/slf4j/Logger.html"; 
>org.slf4j.Logger</a>: logger for the module (derived from the module's class 
name)</li><li><a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ObjectLocator.html";>ObjectLocator</a>:
 access to other services<br clear="none"> Note that the fields are final: this 
is important. Tapestry IoC is thread-safe and you largely never have to think 
about concurrency issues. But in a busy application, different services may be 
built by different threads simultaneously. Each module class is a singleton, 
instantiated at most once, and making these fields final ensures that the 
values are available across multiple threads. Refer to Brian Goetz's <a shape
 ="rect" class="external-link" href="http://www.javaconcurrencyinpractice.com/"; 
>Java Concurrency in Practice</a> for a more complete explanation of the 
relationship between final fields, constructors, and threads ... or just trust 
us!</li></ul><p>Care should be taken with this approach: in some circumstances, 
you may force a situation in which the module constructor is dependent on 
itself. For example, if you invoke a method on any injected services defined 
within the same module from the module class' constructor, then the service 
implementation will be needed. Creating service implementations requires the 
module builder instance ... that's a recursive reference.</p><p>Tapestry 
detects these scenarios and throws a runtime exception to prevent an endless 
loop.</p><h1 id="TapestryIoCModules-ModuleClassImplementationNotes">Module 
Class Implementation Notes</h1><p>Module classes are designed to be very, very 
simple to implement.</p><p>Again, keep the methods very simple. Use <a shape="
 rect" href="defining-tapestry-ioc-services.html">parameter injection</a> to 
gain access to the dependencies you need.</p><p>Be careful about inheritance. 
Tapestry will see all <em>public</em> methods, even those inherited from base 
classes. Tapestry <em>only</em> sees public methods.</p><p>By convention, 
module class names end in Module and are final classes.</p><p>You don't 
<em>have</em> to define your methods as static. The use of static methods is 
only absolutely necessary in a few cases, where the constructor for a module is 
dependent on contributions from the same module (this creates a 
chicken-and-the-egg situation that is resolved through static methods).</p><h1 
id="TapestryIoCModules-DefaultMarker">Default Marker</h1><p>Services are often 
referenced by a particular marker interface on the method or constructor 
parameter. Tapestry will use the intersection of services with that exact 
marker and assignable by type to find a unique service to inject.</p><p>Often, 
all services i
 n a module should share a marker, this can be specified with a @Marker 
annotation on the module class. For example, the TapestryIOCModule:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@Marker(Builtin.class)
 public final class TapestryIOCModule
 {
   . . .</pre>
-</div></div>
-
-<p>This references a particular annotation class, Builtin:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-@Target(
+</div></div><p>This references a particular annotation class, Builtin:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@Target(
 { PARAMETER, FIELD })
 @Retention(RUNTIME)
 @Documented
@@ -230,21 +122,8 @@ public @interface Builtin
 {
 
 }</pre>
-</div></div>
-
-<p>The annotation can be applied to method and constructor parameters, for use 
within the IoC container. It can also be applied to fields, though this is 
specific to the Tapestry web framework.</p>
-
-<h1 id="TapestryIoCModules-FieldInjection">Field Injection</h1>
-
-<p>The @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Inject.html";>Inject</a>
 and @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/InjectService.html";>InjectService</a>
 annotations may be used on instance fields of a module class, as an 
alternative to passing dependencies of the module in via the constructor.</p>
-
-<p>Caution: injection via fields uses reflection to make the fields 
accessible. In addition, it may not be as thread-safe as using the constructor 
to assign to final fields.</p>
-
-<p>Using this style, the previous example of a module class may be 
rewritten:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
-public class MyModule
+</div></div><p>The annotation can be applied to method and constructor 
parameters, for use within the IoC container. It can also be applied to fields, 
though this is specific to the Tapestry web framework.</p><h1 
id="TapestryIoCModules-FieldInjection">Field Injection</h1><p>The @<a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Inject.html";>Inject</a>
 and @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/InjectService.html";>InjectService</a>
 annotations may be used on instance fields of a module class, as an 
alternative to passing dependencies of the module in via the 
constructor.</p><p>Caution: injection via fields uses reflection to make the 
fields accessible. In addition, it may not be as thread-safe as using the 
constructor to assign to final fields.</p><p>Using this style, the previous 
example of a module class may be rewritten:</p><div cl
 ass="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class MyModule
 {
   @Inject
   private JobScheduler scheduler;
@@ -261,8 +140,7 @@ public class MyModule
     return indexer;
   }
 }</pre>
-</div></div>
-</div>
+</div></div><p>&#160;</p><p></p></div>
 </div>
 
 <div class="clearer"></div>


Reply via email to