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 Wed Sep 20 
12:29:16 2017
@@ -27,6 +27,14 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <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>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -36,26 +44,13 @@
 
   <div class="wrapper bs">
 
-        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div>
-
-</div>
+        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div></div>
 
           <div id="top">
-            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";>
-  <input type="text" name="q">
-  <input type="submit" value="Search">
-</form>
-
-</div>
-
-
-<div class="emblem" style="float:left"><p><a  href="index.html"><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div>
-
-
-<div class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Tapestry IoC Modules</h1></div>
-
-</div>
+            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span><form 
enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";> 
+ <input type="text" name="q"> 
+ <input type="submit" value="Search"> 
+</form></div><div class="emblem" style="float:left"><p><a  
href="index.html"><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div><div
 class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Tapestry IoC Modules</h1></div></div>
       <div class="clearer"></div>
       </div>
 
@@ -67,7 +62,8 @@
       </div>
 
       <div id="content">
-                <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 ma
 y 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><parameter ac:name="">java</parameter><plain-text-body>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 ma
 y 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
 {
@@ -75,7 +71,9 @@ public class MyAppModule
   {
     return new IndexerImpl();
   }
-}</plain-text-body><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  
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  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  href="defining-tapestry-ioc-services.html">Defining Tapestry IOC 
Services</a></p><p>An al
 ternate, and usually preferred, way to define a service is via a module's 
bind() method. The previous example can be rewritten as:</p><parameter 
ac:name="">java</parameter><plain-text-body>package org.example.myapp.services;
+}</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 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  
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  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  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;
 
@@ -85,7 +83,9 @@ public class MyAppModule
   {
      binder.bind(Indexer.class, IndexerImpl.class);
   }
-}</plain-text-body><p>For more details, see see <a  
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"><parameter 
ac:name="">Cacheing_Services</parameter>Caching Services</h1><p>You will 
occasionally find yourself in the position of injecting the same services into 
your service builder or service decora
 tor 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  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><parameter 
ac:name="">java</parameter><plain-text-body>public class MyModule
+}</pre>
+</div></div><p>For more details, see see <a  
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 servi
 ce 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  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;
@@ -104,17 +104,23 @@ public class MyAppModule
       
     return indexer;
   }
-}</plain-text-body><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  class="external-link" 
href="http://www.slf4j.org/api/org/slf4j/Logger.html"; 
rel="nofollow">org.slf4j.Logger</a>: logger for the module (derived from the 
module's class name)</li><li><a  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  class="
 external-link" href="http://www.javaconcurrencyinpractice.com/"; 
rel="nofollow">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  href="d
 efining-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 sh
 ould share a marker, this can be specified with a @Marker annotation on the 
module class. For example, the TapestryIOCModule:</p><parameter 
ac:name="">java</parameter><plain-text-body>@Marker(Builtin.class)
+}</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  class="external-link" 
href="http://www.slf4j.org/api/org/slf4j/Logger.html"; 
rel="nofollow">org.slf4j.Logger</a>: logger for the module (derived from the 
module's class name)</li><li><a  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  
class="externa
 l-link" href="http://www.javaconcurrencyinpractice.com/"; rel="nofollow">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  
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 sh
 are 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
 {
-  . . .</plain-text-body><p>This references a particular annotation class, 
Builtin:</p><parameter ac:name="">java</parameter><plain-text-body>@Target(
+  . . .</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(
 { PARAMETER, FIELD })
 @Retention(RUNTIME)
 @Documented
 public @interface Builtin
 {
 
-}</plain-text-body><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  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Inject.html";>Inject</a>
 and @<a  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><parameter ac:name="">ja
 va</parameter><plain-text-body>public class MyModule
+}</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  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Inject.html";>Inject</a>
 and @<a  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" sty
 le="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;
@@ -130,7 +136,8 @@ public @interface Builtin
 
     return indexer;
   }
-}</plain-text-body><p>&#160;</p><p></p></div>
+}</pre>
+</div></div><p>&#160;</p><p></p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/tapestry-ioc-overview.html
==============================================================================
--- websites/production/tapestry/content/tapestry-ioc-overview.html (original)
+++ websites/production/tapestry/content/tapestry-ioc-overview.html Wed Sep 20 
12:29:16 2017
@@ -27,6 +27,14 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <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>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -36,26 +44,13 @@
 
   <div class="wrapper bs">
 
-        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div>
-
-</div>
+        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div></div>
 
           <div id="top">
-            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";>
-  <input type="text" name="q">
-  <input type="submit" value="Search">
-</form>
-
-</div>
-
-
-<div class="emblem" style="float:left"><p><a  href="index.html"><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div>
-
-
-<div class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Tapestry IoC Overview</h1></div>
-
-</div>
+            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span><form 
enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";> 
+ <input type="text" name="q"> 
+ <input type="submit" value="Search"> 
+</form></div><div class="emblem" style="float:left"><p><a  
href="index.html"><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div><div
 class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Tapestry IoC Overview</h1></div></div>
       <div class="clearer"></div>
       </div>
 
@@ -67,7 +62,26 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>Even today, with the 
overwhelming success of <a  class="external-link" 
href="http://www.springframework.org"; rel="nofollow">Spring</a> and the rise of 
smaller, simpler approaches to building applications (in contrast to the 
heavyweight EJB 2.0 approach), many people still have trouble wrapping their 
heads around Inversion of Control.</p><p>Really understanding IoC is a new step 
for many developers. If you can remember back to when you made the transition 
from procedural programming (in C, or BASIC) to object oriented programming, 
you might remember the point where you "got it". The point where it made sense 
to have methods on objects, and data inside objects.</p><p>Inversion of Control 
builds upon those ideas. The goal is to make code more robust (that is, with 
fewer errors), more reusable and much easier to test.</p><p>Prior to IoC 
approaches, most developers were used to a more <em>monolithic</em> design, 
with a few core objects and a
  <code>main()</code> method somewhere that starts the ball rolling. 
<code>main()</code> instantiates the first couple of classes, and those classes 
end up instantiating and using all the other classes in the 
system.</p><p>That's an <em>unmanaged</em> system. Most desktop applications 
are unmanaged, so it's a very familiar pattern, and easy to get your head 
around.</p><p>By contrast, web applications are a <em>managed</em> environment. 
You don't write a main(), you don't control startup. You <em>configure</em> the 
Servlet API to tell it about your servlet classes to be instantiated, and their 
life cycle is totally controlled by the servlet container.</p><p>Inversion of 
Control is just a more general application of this approach. The container is 
ultimately responsible for instantiating and configuring the objects you tell 
it about, and running their entire life cycle of those objects.</p><p>Web 
applications are more complicated to write than monolithic applications, 
largely because o
 f <em>multithreading</em>. Your code will be servicing many different users 
simultaneously across many different threads. This tends to complicate the code 
you write, since some fundamental aspects of object oriented development get 
called into question: in particular, the use of <em>internal state</em> (values 
stored inside instance variables), since in a multithreaded environment, that's 
no longer the safe place it is in traditional development. Shared objects plus 
internal state plus multiple threads equals an broken, unpredictable 
application.</p><p>Frameworks such as Tapestry &#8211; both the IoC container, 
and the web framework itself &#8211; exist to help.</p><p>When thinking in 
terms of IoC, <strong>small is beautiful</strong>. What does that mean? It 
means small classes and small methods are easier to code than large ones. At 
one extreme, we have servlets circa 1997 (and Visual Basic before that) with 
methods a thousand lines long, and no distinction between business logic 
 and view logic. Everything mixed together into an untestable jumble.</p><p>At 
the other extreme is IoC: small objects, each with a specific purpose, 
collaborating with other small objects.</p><p>Using unit tests, in 
collaboration with tools such as <a  class="external-link" 
href="http://easymock.org/"; rel="nofollow">EasyMock</a>, you can have a code 
base that is easy to maintain, easy to extend, and easy to test. And by 
factoring out a lot of <em>plumbing</em> code, your code base will not only be 
easier to work with, it will be smaller.</p><h2 
id="TapestryIoCOverview-LivingontheFrontier">Living on the 
Frontier</h2><p>Coding applications the traditional way is like being a 
homesteader on the American frontier in the 1800's. You're responsible for 
every aspect of your house: every board, every nail, every stick of furniture 
is something you personally created. There <em>is</em> a great comfort in total 
self reliance. Even if your house is small, the windows are a bit drafty or the 
fl
 oorboards creak a little, you know exactly <em>why</em> things are not-quite 
perfect.</p><p>Flash forward to modern cities or modern suburbia and it's a 
whole different story. Houses are built to specification from design plans, 
made from common materials, by many specializing tradespeople. Construction 
codes dictate how plumbing, wiring and framing should be performed. A 
home-owner may not even know how to drive a nail, but can still take comfort in 
draft-free windows, solid floors and working plumbing.</p><p>To extend the 
metaphor, a house in a town is not alone and self-reliant the way a frontier 
house is. The town house is situated on a street, in a neighborhood, within a 
town. The town provides services (utilities, police, fire control, streets and 
sewers) to houses in a uniform way. Each house just needs to connect up to 
those services.</p><h2 id="TapestryIoCOverview-TheWorldoftheContainer">The 
World of the Container</h2><p>So the IoC container is the "town" and in the 
world o
 f the IoC container, everything has a name, a place, and a relationship to 
everything else in the container. Tapestry calls this world "The 
Registry".</p><p><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image" 
src="tapestry-ioc-overview.data/ioc-overview.png"></span></p><p>Here we're 
seeing a few services from the built-in Tapestry IoC module, and a few of the 
services from the Tapestry web framework module. In fact, there are over 100 
services, all interrelated, in the Registry ... and that's before you add your 
own to the mix. The IoC Registry treats all the services uniformly, regardless 
of whether they are part of Tapestry, or part of your application, or part of 
an add-on library.</p><p>Tapestry IoC's job is to make all of these services 
available to each other, and to the outside world. The outside world could be a 
standalone application, or it could be an application built on top of the 
Tapestry web framework.</p><h2 id="TapestryIoCOverview-Se
 rviceLifeCycle">Service Life Cycle</h2><p>Tapestry services are <em>lazy</em>, 
which means they are not fully instantiated until they are absolutely needed. 
Often, what looks like a service is really a proxy object ... the first time 
any method of the proxy is invoked, the actual service is instantiated and 
initialized (Tapestry uses the term <em>realized</em> for this process). Of 
course, this is all absolutely thread-safe.</p><p>Initially a service is 
<em>defined</em>, meaning some module has defined the service. Later, the 
service will be <em>virtual</em>, meaning a proxy has been created. This occurs 
most often because some other service <em>depends</em> on it, but hasn't gotten 
around to invoking methods on it. Finally, a service that is ready to use is 
<em>realized</em>. What's nice is that your code neither knows nor cares about 
the life cycle of the service, because of the magic of the proxy.</p><p>In 
fact, when a Tapestry web application starts up, before it services its fi
 rst request, only about 20% of the services have been realized; the remainder 
are defined or virtual.</p><h2 id="TapestryIoCOverview-Classvs.Service">Class 
vs. Service</h2><p>A Tapestry service is more than just a class. First of all, 
it is a combination of an <em>interface</em> that defines the operations of the 
service, and an <em>implementation class</em> that implements the 
interface.</p><p>Why this extra division? Having a service interface is what 
lets Tapestry create proxies and perform other operations. It's also a very 
good practice to code to an interface, rather than a specific implementation. 
You'll often be surprised at the kinds of things you can accomplish by 
substituting one implementation for another.</p><p>Tapestry is also very aware 
that a service will have dependencies on other services. It may also have other 
needs ... for example, in Tapestry IoC, the container provides services with 
access to Loggers.</p><p>Tapestry IoC also has support for other configuration
  that may be provided to services when they are realized.</p><h2 
id="TapestryIoCOverview-DependencyInjection">Dependency Injection</h2><p>Main 
Article: <a  href="injection.html">Injection</a></p><parameter 
ac:name="style">float:right</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter 
ac:name="class">aui-label</parameter><rich-text-body><parameter 
ac:name="showLabels">false</parameter><parameter 
ac:name="showSpace">false</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter ac:name="cql">label = "injection" and space = 
currentSpace()</parameter></rich-text-body><p>Inversion of Control refers to 
the fact that the container, here Tapestry IoC's Registry, instantiates your 
classes. It decides on when the classes get instantiated.</p><p>Dependency 
Injection is a key part of <em>realization</em>: this is how a service is 
provided with the other services it needs to operate. For example, a Data 
Access Object service may be injected with a Co
 nnectionPool service.</p><p>In Tapestry, injection occurs through 
constructors, through parameters to service builder methods, or through direct 
injection into fields. Tapestry prefers constructor injection, as this 
emphasizes that dependencies should be stored in <strong>final</strong> 
variables. This is the best approach towards ensuring thread safety.</p><p>In 
any case, injection "just happens". Tapestry finds the constructor of your 
class and analyzes the parameters to determine what to pass in. In some cases, 
it uses just the parameter type to find a match, in other cases, annotations on 
the parameters may also be used. It also scans through the fields of your 
service implementation class to identify which should have injected values 
written into them.</p><h2 id="TapestryIoCOverview-Whycan'tIjustusenew?">Why 
can't I just use <code>new</code>?</h2><p>That's a common question. All these 
concepts seem alien at first. What's wrong with <code>new</code>?</p><p>The 
problem with new i
 s that it rigidly connects one implementation to another implementation. Let's 
follow a progression that reflects how a lot of projects get written. It will 
show that in the real world, <code>new</code> is not as simple as it first 
seems.</p><p>This example is built around some real-world work that involves a 
Java Messaging Service queue, part of an application performance monitoring 
subsystem for a large application. Code inside each server collects performance 
data of various types and sends it, via a shared JMS queue, to a central server 
for collection and reporting.</p><p>This code is for a metric that periodically 
counts the number of rows in a key database table. Other implementations of 
MetricProducer will be responsible for measuring CPU utilization, available 
disk space, number of requests per second, and so forth.</p><parameter 
ac:name="">java</parameter><plain-text-body>public class TableMetricProducer 
implements MetricProducer
+                <div id="ConfluenceContent"><p>Even today, with the 
overwhelming success of <a  class="external-link" 
href="http://www.springframework.org"; rel="nofollow">Spring</a> and the rise of 
smaller, simpler approaches to building applications (in contrast to the 
heavyweight EJB 2.0 approach), many people still have trouble wrapping their 
heads around Inversion of Control.</p><p>Really understanding IoC is a new step 
for many developers. If you can remember back to when you made the transition 
from procedural programming (in C, or BASIC) to object oriented programming, 
you might remember the point where you "got it". The point where it made sense 
to have methods on objects, and data inside objects.</p><p>Inversion of Control 
builds upon those ideas. The goal is to make code more robust (that is, with 
fewer errors), more reusable and much easier to test.</p><p>Prior to IoC 
approaches, most developers were used to a more <em>monolithic</em> design, 
with a few core objects and a
  <code>main()</code> method somewhere that starts the ball rolling. 
<code>main()</code> instantiates the first couple of classes, and those classes 
end up instantiating and using all the other classes in the 
system.</p><p>That's an <em>unmanaged</em> system. Most desktop applications 
are unmanaged, so it's a very familiar pattern, and easy to get your head 
around.</p><p>By contrast, web applications are a <em>managed</em> environment. 
You don't write a main(), you don't control startup. You <em>configure</em> the 
Servlet API to tell it about your servlet classes to be instantiated, and their 
life cycle is totally controlled by the servlet container.</p><p>Inversion of 
Control is just a more general application of this approach. The container is 
ultimately responsible for instantiating and configuring the objects you tell 
it about, and running their entire life cycle of those objects.</p><p>Web 
applications are more complicated to write than monolithic applications, 
largely because o
 f <em>multithreading</em>. Your code will be servicing many different users 
simultaneously across many different threads. This tends to complicate the code 
you write, since some fundamental aspects of object oriented development get 
called into question: in particular, the use of <em>internal state</em> (values 
stored inside instance variables), since in a multithreaded environment, that's 
no longer the safe place it is in traditional development. Shared objects plus 
internal state plus multiple threads equals an broken, unpredictable 
application.</p><p>Frameworks such as Tapestry &#8211; both the IoC container, 
and the web framework itself &#8211; exist to help.</p><p>When thinking in 
terms of IoC, <strong>small is beautiful</strong>. What does that mean? It 
means small classes and small methods are easier to code than large ones. At 
one extreme, we have servlets circa 1997 (and Visual Basic before that) with 
methods a thousand lines long, and no distinction between business logic 
 and view logic. Everything mixed together into an untestable jumble.</p><p>At 
the other extreme is IoC: small objects, each with a specific purpose, 
collaborating with other small objects.</p><p>Using unit tests, in 
collaboration with tools such as <a  class="external-link" 
href="http://easymock.org/"; rel="nofollow">EasyMock</a>, you can have a code 
base that is easy to maintain, easy to extend, and easy to test. And by 
factoring out a lot of <em>plumbing</em> code, your code base will not only be 
easier to work with, it will be smaller.</p><h2 
id="TapestryIoCOverview-LivingontheFrontier">Living on the 
Frontier</h2><p>Coding applications the traditional way is like being a 
homesteader on the American frontier in the 1800's. You're responsible for 
every aspect of your house: every board, every nail, every stick of furniture 
is something you personally created. There <em>is</em> a great comfort in total 
self reliance. Even if your house is small, the windows are a bit drafty or the 
fl
 oorboards creak a little, you know exactly <em>why</em> things are not-quite 
perfect.</p><p>Flash forward to modern cities or modern suburbia and it's a 
whole different story. Houses are built to specification from design plans, 
made from common materials, by many specializing tradespeople. Construction 
codes dictate how plumbing, wiring and framing should be performed. A 
home-owner may not even know how to drive a nail, but can still take comfort in 
draft-free windows, solid floors and working plumbing.</p><p>To extend the 
metaphor, a house in a town is not alone and self-reliant the way a frontier 
house is. The town house is situated on a street, in a neighborhood, within a 
town. The town provides services (utilities, police, fire control, streets and 
sewers) to houses in a uniform way. Each house just needs to connect up to 
those services.</p><h2 id="TapestryIoCOverview-TheWorldoftheContainer">The 
World of the Container</h2><p>So the IoC container is the "town" and in the 
world o
 f the IoC container, everything has a name, a place, and a relationship to 
everything else in the container. Tapestry calls this world "The 
Registry".</p><p><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image" 
src="tapestry-ioc-overview.data/ioc-overview.png"></span></p><p>Here we're 
seeing a few services from the built-in Tapestry IoC module, and a few of the 
services from the Tapestry web framework module. In fact, there are over 100 
services, all interrelated, in the Registry ... and that's before you add your 
own to the mix. The IoC Registry treats all the services uniformly, regardless 
of whether they are part of Tapestry, or part of your application, or part of 
an add-on library.</p><p>Tapestry IoC's job is to make all of these services 
available to each other, and to the outside world. The outside world could be a 
standalone application, or it could be an application built on top of the 
Tapestry web framework.</p><h2 id="TapestryIoCOverview-Se
 rviceLifeCycle">Service Life Cycle</h2><p>Tapestry services are <em>lazy</em>, 
which means they are not fully instantiated until they are absolutely needed. 
Often, what looks like a service is really a proxy object ... the first time 
any method of the proxy is invoked, the actual service is instantiated and 
initialized (Tapestry uses the term <em>realized</em> for this process). Of 
course, this is all absolutely thread-safe.</p><p>Initially a service is 
<em>defined</em>, meaning some module has defined the service. Later, the 
service will be <em>virtual</em>, meaning a proxy has been created. This occurs 
most often because some other service <em>depends</em> on it, but hasn't gotten 
around to invoking methods on it. Finally, a service that is ready to use is 
<em>realized</em>. What's nice is that your code neither knows nor cares about 
the life cycle of the service, because of the magic of the proxy.</p><p>In 
fact, when a Tapestry web application starts up, before it services its fi
 rst request, only about 20% of the services have been realized; the remainder 
are defined or virtual.</p><h2 id="TapestryIoCOverview-Classvs.Service">Class 
vs. Service</h2><p>A Tapestry service is more than just a class. First of all, 
it is a combination of an <em>interface</em> that defines the operations of the 
service, and an <em>implementation class</em> that implements the 
interface.</p><p>Why this extra division? Having a service interface is what 
lets Tapestry create proxies and perform other operations. It's also a very 
good practice to code to an interface, rather than a specific implementation. 
You'll often be surprised at the kinds of things you can accomplish by 
substituting one implementation for another.</p><p>Tapestry is also very aware 
that a service will have dependencies on other services. It may also have other 
needs ... for example, in Tapestry IoC, the container provides services with 
access to Loggers.</p><p>Tapestry IoC also has support for other configuration
  that may be provided to services when they are realized.</p><h2 
id="TapestryIoCOverview-DependencyInjection">Dependency Injection</h2><p>Main 
Article: <a  href="injection.html">Injection</a></p><div class="aui-label" 
style="float:right" title="Related Articles"><h3>Related Articles</h3><ul 
class="content-by-label"><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="injection-in-detail.html">Injection in Detail</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="injection-faq.html">Injection FAQ</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="injection.html">Injection</a> 
+  </div> </li></ul></div><p>Inversion of Control refers to the fact that the 
container, here Tapestry IoC's Registry, instantiates your classes. It decides 
on when the classes get instantiated.</p><p>Dependency Injection is a key part 
of <em>realization</em>: this is how a service is provided with the other 
services it needs to operate. For example, a Data Access Object service may be 
injected with a ConnectionPool service.</p><p>In Tapestry, injection occurs 
through constructors, through parameters to service builder methods, or through 
direct injection into fields. Tapestry prefers constructor injection, as this 
emphasizes that dependencies should be stored in <strong>final</strong> 
variables. This is the best approach towards ensuring thread safety.</p><p>In 
any case, injection "just happens". Tapestry finds the constructor of your 
class and analyzes the parameters to determine what to pass in. In some cases, 
it uses just the parameter type to find a match, in other cases, annota
 tions on the parameters may also be used. It also scans through the fields of 
your service implementation class to identify which should have injected values 
written into them.</p><h2 id="TapestryIoCOverview-Whycan'tIjustusenew?">Why 
can't I just use <code>new</code>?</h2><p>That's a common question. All these 
concepts seem alien at first. What's wrong with <code>new</code>?</p><p>The 
problem with new is that it rigidly connects one implementation to another 
implementation. Let's follow a progression that reflects how a lot of projects 
get written. It will show that in the real world, <code>new</code> is not as 
simple as it first seems.</p><p>This example is built around some real-world 
work that involves a Java Messaging Service queue, part of an application 
performance monitoring subsystem for a large application. Code inside each 
server collects performance data of various types and sends it, via a shared 
JMS queue, to a central server for collection and reporting.</p><p>This cod
 e is for a metric that periodically counts the number of rows in a key 
database table. Other implementations of MetricProducer will be responsible for 
measuring CPU utilization, available disk space, number of requests per second, 
and so forth.</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 TableMetricProducer implements 
MetricProducer
 {
   . . . 
 
@@ -78,7 +92,9 @@
     new QueueWriter().sendMetric(metric);
   }
 }
-</plain-text-body><p>We've omitted some of the details (this code will need a 
database URL or a connection pool to operate), so as to focus on the one method 
and it's relationship to the QueueWriter class.</p><p>Obviously, this code has 
a problem ... we're creating a new QueueWriter for each metric we write into 
the queue, and the QueueWriter presumably is going to open the JMS queue fresh 
each time, an expensive operation. Thus:</p><parameter 
ac:name="">java</parameter><plain-text-body>public class TableMetricProducer 
implements MetricProducer
+</pre>
+</div></div><p>We've omitted some of the details (this code will need a 
database URL or a connection pool to operate), so as to focus on the one method 
and it's relationship to the QueueWriter class.</p><p>Obviously, this code has 
a problem ... we're creating a new QueueWriter for each metric we write into 
the queue, and the QueueWriter presumably is going to open the JMS queue fresh 
each time, an expensive operation. Thus:</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 TableMetricProducer implements 
MetricProducer
 {
   . . . 
 
@@ -89,7 +105,11 @@
     int rowCount = . . .;
     Metric metric = new Metric("app/clients", System.currentTimeMillis(), 
rowCount);
     queueWriter.sendMetric(metric);
-  }</plain-text-body><p>That's better. It's not perfect ... a proper system 
might know when the application was being shutdown and would shut down the JMS 
Connection inside the QueueWriter as well.</p><p>Here's a more immediate 
problem: JMS connections are really meant to be shared, and we'll have lots of 
little classes collecting different metrics. So we need to make the QueueWriter 
shareable:</p><parameter ac:name="">java</parameter><plain-text-body>  private 
final QueueWriter queueWriter = 
QueueWriter.getInstance();</plain-text-body><p>... and inside class 
QueueWriter:</p><parameter ac:name="">java</parameter><plain-text-body>public 
class QueueWriter
+  }</pre>
+</div></div><p>That's better. It's not perfect ... a proper system might know 
when the application was being shutdown and would shut down the JMS Connection 
inside the QueueWriter as well.</p><p>Here's a more immediate problem: JMS 
connections are really meant to be shared, and we'll have lots of little 
classes collecting different metrics. So we need to make the QueueWriter 
shareable:</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;">  private final QueueWriter queueWriter = 
QueueWriter.getInstance();</pre>
+</div></div><p>... and inside class QueueWriter:</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 QueueWriter
 {
   private static QueueWriter instance;
 
@@ -107,7 +127,9 @@
     return instance;
   }
 }
-</plain-text-body><p>Much better! Now all the metric producers running inside 
all the threads can share a single QueueWriter. Oh wait ...</p><parameter 
ac:name="">java</parameter><plain-text-body>  public synchronized static 
getInstance()
+</pre>
+</div></div><p>Much better! Now all the metric producers running inside all 
the threads can share a single QueueWriter. Oh wait ...</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 synchronized static getInstance()
   {
     if (instance == null)
     {
@@ -115,7 +137,9 @@
     }
     return instance;
   }
-</plain-text-body><p>Is that necessary? Yes. Will the code work without it? 
Yes &#8211; <strong>99.9% of the time</strong>. In fact, this is a very common 
error in systems that manually code a lot of these construction patterns: 
forgetting to properly synchronize access. These things often work in 
development and testing, but fail (with infuriating infrequency) in production, 
as it takes two or more threads running simultaneously to reveal the coding 
error.</p><p>Wow, we're a long way from a simple <code>new</code> already, and 
we're talking about just one service. But let's detour into 
<em>testing</em>.</p><p>How would you test TableMetricProducer? One way would 
be to let it run and try to find the message or messages it writes in the 
queue, but that seems fraught with difficulties. It's more of an integration 
test, and is certainly something that you'd want to execute at some stage of 
your development, but not as part of a quick-running unit test 
suite.</p><p>Instead, let's split 
 QueueWriter in two: a QueueWriter interface, and a QueueWriterImpl 
implementation class. This will allow us to run TableMetricProducer against a 
<em>mock implementation</em> of QueueWriter, rather than the real thing. This 
is one of the immediate benefits of <em>coding to an interface</em> rather than 
<em>coding to an implementation</em>.</p><p>We'll need to change 
TableMetricProducer to take the QueueWriter as a constructor 
parameter.</p><parameter ac:name="">java</parameter><plain-text-body>public 
class TableMetricProducer implements MetricProducer
+</pre>
+</div></div><p>Is that necessary? Yes. Will the code work without it? Yes 
&#8211; <strong>99.9% of the time</strong>. In fact, this is a very common 
error in systems that manually code a lot of these construction patterns: 
forgetting to properly synchronize access. These things often work in 
development and testing, but fail (with infuriating infrequency) in production, 
as it takes two or more threads running simultaneously to reveal the coding 
error.</p><p>Wow, we're a long way from a simple <code>new</code> already, and 
we're talking about just one service. But let's detour into 
<em>testing</em>.</p><p>How would you test TableMetricProducer? One way would 
be to let it run and try to find the message or messages it writes in the 
queue, but that seems fraught with difficulties. It's more of an integration 
test, and is certainly something that you'd want to execute at some stage of 
your development, but not as part of a quick-running unit test 
suite.</p><p>Instead, let's split QueueW
 riter in two: a QueueWriter interface, and a QueueWriterImpl implementation 
class. This will allow us to run TableMetricProducer against a <em>mock 
implementation</em> of QueueWriter, rather than the real thing. This is one of 
the immediate benefits of <em>coding to an interface</em> rather than 
<em>coding to an implementation</em>.</p><p>We'll need to change 
TableMetricProducer to take the QueueWriter as a constructor parameter.</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 TableMetricProducer implements 
MetricProducer
 {
   private final QueueWriter queueWriter;
 
@@ -146,7 +170,9 @@
    queueWriter.sendMetric(metric);
   }
 }
-</plain-text-body><p>This still isn't ideal, as we still have an explicit 
linkage between TableMetricProducer and QueueWriterImpl.</p><p>What we're 
seeing here is that there are multple <em>concerns</em> inside the little bit 
of code in this example. TableMetricProducer has an unwanted <em>construction 
concern</em> about which implementation of QueueWriter to instantiate (this 
shows up as two constructors, rather than just one). QueueWriterImpl has an 
additional <em>life cycle concern</em>, in terms of managing the 
singleton.</p><p>These extra concerns, combined with the use of static 
variables and methods, are a <em>bad design smell</em>. It's not yet very 
stinky, because this example is so small, but these problems tend to multiply 
as an application grows larger and more complex, especially as services start 
to truly collaborate in earnest.</p><p>For comparison, lets see what the 
Tapestry IoC implementation would look like:</p><parameter 
ac:name="">java</parameter><plain-text-body
 >public class MonitorModule
+</pre>
+</div></div><p>This still isn't ideal, as we still have an explicit linkage 
between TableMetricProducer and QueueWriterImpl.</p><p>What we're seeing here 
is that there are multple <em>concerns</em> inside the little bit of code in 
this example. TableMetricProducer has an unwanted <em>construction concern</em> 
about which implementation of QueueWriter to instantiate (this shows up as two 
constructors, rather than just one). QueueWriterImpl has an additional <em>life 
cycle concern</em>, in terms of managing the singleton.</p><p>These extra 
concerns, combined with the use of static variables and methods, are a <em>bad 
design smell</em>. It's not yet very stinky, because this example is so small, 
but these problems tend to multiply as an application grows larger and more 
complex, especially as services start to truly collaborate in 
earnest.</p><p>For comparison, lets see what the Tapestry IoC implementation 
would look like:</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 MonitorModule
 {
   public static void bind(ServiceBinder binder)
   {
@@ -159,7 +185,8 @@
     configuration.add(new TableMetricProducer(queueWriter, . . .))
   }
 }
-</plain-text-body><p>Again, we've omitted a few details related to the 
database the TableMetricProducer will point at (in fact, Tapestry IoC provides 
a lot of support for configuration of this type as well, which is yet another 
concern).</p><p>The MonitorModule class is a Tapestry IoC module: a class that 
defines and configures services.</p><p>The bind() method is the principle way 
that services are made known to the Registry: here we're binding a service 
interface to a service implementation. QueueWriter we've discussed already, and 
MetricScheduler is a service that is responsible for determining when 
MetricProducer instances run.</p><p>The contributeMetricScheduler() method 
allows the module to <em>contribute</em> into the MetricProducer service's 
<em>configuration</em>. More testability: the MetricProducer isn't tied to a 
pre-set list of producers, instead it will have a 
Collection&lt;MetricProducer&gt; injected into its constructor. Thus, when 
we're coding the MetricProducerImpl
  class, we can test it against mock implementations of 
MetricProducer.</p><p>The QueueWriter service is injected into the 
contributeMetricScheduler() method. Since there's only one QueueWriter service, 
Tapestry IoC is able to "find" the correct service based entirely on type. If, 
eventually, there's more than one QueueWriter service (perhaps pointing at 
different JMS queues), you would use an annotation on the parameter to help 
Tapestry connect the parameter to the appropriate service.</p><p>Presumably, 
there would be a couple of other parameters to the contributeMetricScheduler() 
method, to inject in a database URL or connection pool (that would, in turn, be 
passed to TableMetricProducer).</p><p>A new TableMetricProducer instance is 
created and contributed in. We could contribute as many producers as we like 
here. Other modules could also define a contributeMetricScheduler() method and 
contribute their own MetricProducer instances.</p><p>Meanwhile, the 
QueueWriterImpl class no long
 er needs the <code>instance</code> variable or getInstance() method, and the 
TableMetricProducer only needs a single constructor.</p><h2 
id="TapestryIoCOverview-AdvantagesofIoC:Summary">Advantages of IoC: 
Summary</h2><p>It would be ludicrous for us to claim that applications built 
without an IoC container are doomed to failure. There is overwhelming evidence 
that applications have been built without containers and have been perfectly 
successful.</p><p>What we are saying is that IoC techniques and discipline will 
lead to applications that are:</p><ul><li>More testable &#8211; smaller, 
simpler classes; coding to interfaces allows use of mock 
implementations</li><li>More robust &#8211; smaller, simpler classes; use of 
final variables; thread safety baked in</li><li>More scalable &#8211; thread 
safety baked in</li><li>Easier to maintain &#8211; less code, simpler 
classes</li><li>Easier to extend &#8211; new features are often additions (new 
services, new contributions) rather than chang
 es to existing classes</li></ul><p>What we're saying is that an IoC container 
allows you to work faster and smarter.</p><p>Many of these traits work 
together; for example, a more testable application is inherently more robust. 
Having a test suite makes it easier to maintain and extend your code, because 
its much easier to see if new features break existing ones. Simpler code plus 
tests also lowers the cost of entry for new developers coming on board, which 
allows for more developers to work efficiently on the same code base. The clean 
separation between interface and implementation also allows multiple developers 
to work on different aspects of the same code base with a lowered risk of 
interference and conflict.</p><p>By contrast, traditional applications, which 
we term <em>monolithic</em> applications, are often very difficult to test, 
because there are fewer classes, and each class has multiple concerns. A lack 
of tests makes it more difficult to add new features without breaking 
 existing features. Further, the monolithic approach more often leads to 
implementations being linked to other implementations, yet another hurdle 
standing in the way of testing.</p><p>Let's end with a metaphor.</p><p>Over a 
decade ago, when Java first came on the scene, it was the first mainstream 
language to support garbage collection. This was very controversial: the 
garbage collector was seen as unnecessary, and a waste of resources. Among C 
and C++ developers, the attitude was "Why do I need a garbage collector? If I 
call malloc() I can call free()."</p><p>But now, most developers would never 
want to go back to a non-garbage collected environment. Having the GC around 
makes it much easier to code in a way we find natural: many small related 
objects working together. It turns out that knowing when to call free() is more 
difficult than it sounds. The Objective-C language tried to solve this with 
retain counts on objects and that still lead to memory leaks when it was 
applied to ob
 ject <em>graphs</em> rather than object <em>trees</em>.</p><p>Roll the clock 
forward a decade and the common consensus has shifted considerably. Objective-C 
2.0 features true garbage collection and GC libraries are available for C and 
C++. All scripting languages, including Ruby and Python, feature garbage 
collection as well. A new language <em>without</em> garbage collection is now 
considered an anomaly.</p><p>The point is, the life cycle of objects turns out 
to be far more complicated than it looks at first glance. We've come to accept 
that our own applications lack the ability to police their objects as they are 
no longer needed (they literally lack the ability to determine <em>when</em> an 
object is no longer needed) and the garbage collector, a kind of higher 
authority, takes over that job very effectively. The end result? Less code and 
fewer bugs. And a careful study shows that the Java memory allocator and 
garbage collector (the two are quite intimately tied together) is actu
 ally <strong>more</strong> efficient than malloc() and free().</p><p>So we've 
come to accept that the <em>death concern</em> is better handled outside of our 
own code. The use of Inversion of Control is simply the flip side of that: the 
<em>life cycle and construction concerns</em> are also better handled by an 
outside authority as well: the IoC container. These concerns govern when a 
service is <em>realized</em> and how its dependencies and configuration are 
injected. As with the garbage collector, ceding these chores to the container 
results in less code and fewer bugs, and lets you concentrate on the things 
that should matter to you: your business logic, your application &#8211; and 
not a whole bunch of boilerplate plumbing!</p><p>&#160;</p><p></p></div>
+</pre>
+</div></div><p>Again, we've omitted a few details related to the database the 
TableMetricProducer will point at (in fact, Tapestry IoC provides a lot of 
support for configuration of this type as well, which is yet another 
concern).</p><p>The MonitorModule class is a Tapestry IoC module: a class that 
defines and configures services.</p><p>The bind() method is the principle way 
that services are made known to the Registry: here we're binding a service 
interface to a service implementation. QueueWriter we've discussed already, and 
MetricScheduler is a service that is responsible for determining when 
MetricProducer instances run.</p><p>The contributeMetricScheduler() method 
allows the module to <em>contribute</em> into the MetricProducer service's 
<em>configuration</em>. More testability: the MetricProducer isn't tied to a 
pre-set list of producers, instead it will have a 
Collection&lt;MetricProducer&gt; injected into its constructor. Thus, when 
we're coding the MetricProducerImpl class
 , we can test it against mock implementations of MetricProducer.</p><p>The 
QueueWriter service is injected into the contributeMetricScheduler() method. 
Since there's only one QueueWriter service, Tapestry IoC is able to "find" the 
correct service based entirely on type. If, eventually, there's more than one 
QueueWriter service (perhaps pointing at different JMS queues), you would use 
an annotation on the parameter to help Tapestry connect the parameter to the 
appropriate service.</p><p>Presumably, there would be a couple of other 
parameters to the contributeMetricScheduler() method, to inject in a database 
URL or connection pool (that would, in turn, be passed to 
TableMetricProducer).</p><p>A new TableMetricProducer instance is created and 
contributed in. We could contribute as many producers as we like here. Other 
modules could also define a contributeMetricScheduler() method and contribute 
their own MetricProducer instances.</p><p>Meanwhile, the QueueWriterImpl class 
no longer nee
 ds the <code>instance</code> variable or getInstance() method, and the 
TableMetricProducer only needs a single constructor.</p><h2 
id="TapestryIoCOverview-AdvantagesofIoC:Summary">Advantages of IoC: 
Summary</h2><p>It would be ludicrous for us to claim that applications built 
without an IoC container are doomed to failure. There is overwhelming evidence 
that applications have been built without containers and have been perfectly 
successful.</p><p>What we are saying is that IoC techniques and discipline will 
lead to applications that are:</p><ul><li>More testable &#8211; smaller, 
simpler classes; coding to interfaces allows use of mock 
implementations</li><li>More robust &#8211; smaller, simpler classes; use of 
final variables; thread safety baked in</li><li>More scalable &#8211; thread 
safety baked in</li><li>Easier to maintain &#8211; less code, simpler 
classes</li><li>Easier to extend &#8211; new features are often additions (new 
services, new contributions) rather than changes to 
 existing classes</li></ul><p>What we're saying is that an IoC container allows 
you to work faster and smarter.</p><p>Many of these traits work together; for 
example, a more testable application is inherently more robust. Having a test 
suite makes it easier to maintain and extend your code, because its much easier 
to see if new features break existing ones. Simpler code plus tests also lowers 
the cost of entry for new developers coming on board, which allows for more 
developers to work efficiently on the same code base. The clean separation 
between interface and implementation also allows multiple developers to work on 
different aspects of the same code base with a lowered risk of interference and 
conflict.</p><p>By contrast, traditional applications, which we term 
<em>monolithic</em> applications, are often very difficult to test, because 
there are fewer classes, and each class has multiple concerns. A lack of tests 
makes it more difficult to add new features without breaking existi
 ng features. Further, the monolithic approach more often leads to 
implementations being linked to other implementations, yet another hurdle 
standing in the way of testing.</p><p>Let's end with a metaphor.</p><p>Over a 
decade ago, when Java first came on the scene, it was the first mainstream 
language to support garbage collection. This was very controversial: the 
garbage collector was seen as unnecessary, and a waste of resources. Among C 
and C++ developers, the attitude was "Why do I need a garbage collector? If I 
call malloc() I can call free()."</p><p>But now, most developers would never 
want to go back to a non-garbage collected environment. Having the GC around 
makes it much easier to code in a way we find natural: many small related 
objects working together. It turns out that knowing when to call free() is more 
difficult than it sounds. The Objective-C language tried to solve this with 
retain counts on objects and that still lead to memory leaks when it was 
applied to object <
 em>graphs</em> rather than object <em>trees</em>.</p><p>Roll the clock forward 
a decade and the common consensus has shifted considerably. Objective-C 2.0 
features true garbage collection and GC libraries are available for C and C++. 
All scripting languages, including Ruby and Python, feature garbage collection 
as well. A new language <em>without</em> garbage collection is now considered 
an anomaly.</p><p>The point is, the life cycle of objects turns out to be far 
more complicated than it looks at first glance. We've come to accept that our 
own applications lack the ability to police their objects as they are no longer 
needed (they literally lack the ability to determine <em>when</em> an object is 
no longer needed) and the garbage collector, a kind of higher authority, takes 
over that job very effectively. The end result? Less code and fewer bugs. And a 
careful study shows that the Java memory allocator and garbage collector (the 
two are quite intimately tied together) is actually <
 strong>more</strong> efficient than malloc() and free().</p><p>So we've come 
to accept that the <em>death concern</em> is better handled outside of our own 
code. The use of Inversion of Control is simply the flip side of that: the 
<em>life cycle and construction concerns</em> are also better handled by an 
outside authority as well: the IoC container. These concerns govern when a 
service is <em>realized</em> and how its dependencies and configuration are 
injected. As with the garbage collector, ceding these chores to the container 
results in less code and fewer bugs, and lets you concentrate on the things 
that should matter to you: your business logic, your application &#8211; and 
not a whole bunch of boilerplate plumbing!</p><p>&#160;</p><p></p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to