Author: buildbot
Date: Sun Feb 18 19:21:00 2018
New Revision: 1025566

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/cache/main.pageCache
    websites/production/tapestry/content/development-dashboard.html
    websites/production/tapestry/content/integration-testing.html
    websites/production/tapestry/content/ioc.html
    websites/production/tapestry/content/tapestry-ioc-modules.html
    websites/production/tapestry/content/tapestry-ioc-overview.html
    websites/production/tapestry/content/unit-testing-pages-or-components.html

Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.

Modified: websites/production/tapestry/content/development-dashboard.html
==============================================================================
--- websites/production/tapestry/content/development-dashboard.html (original)
+++ websites/production/tapestry/content/development-dashboard.html Sun Feb 18 
19:21:00 2018
@@ -67,7 +67,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>The <strong>development 
dashboard</strong> is a built-in Tapestry page that can help identify and 
resolve problems in your application.</p><p>The dashboard is typically only 
available to requests from localhost (the page is whitelist access only, see <a 
 href="development-dashboard.html">Development Dashboard</a>).</p><p><span>Some 
features of the dashboard are only available in development 
mode.</span></p><p>The dashboard is available via the URI "core/t5dashboard", 
or can be accessed by the <a  class="external-link" 
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/DevTool.html";>DevTool</a>
 component's dropdown menu.</p><p><span>&#160;<span 
class="confluence-embedded-file-wrapper image-center-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image 
image-center" width="500" 
src="development-dashboard.data/Tapestry_5_Dashboard_-_pages.png"></span></span></p><p>By
 default, there a
 re three tabs (this is extensible).</p><h2 
id="DevelopmentDashboard-Pages">Pages</h2><p>The pages tab shows what pages are 
currently loaded into the application. Tapestry only loads a page when it is 
first needed.</p><p>It is possible to clear out Tapestry's caches, forcing a 
reload. You can also run a garbage collection (GC).</p><p>It is possible to 
load any individual page, or attempt to load all pages. This can be a good way 
to see if all pages (and templates) are error free ... loading all will catch 
quite a few potential errors.</p><h2 
id="DevelopmentDashboard-Services">Services</h2><p>When using Tapestry there 
will often be a large number of services defined in the registry; a mix of the 
built-in services provided by the framework and your own.</p><p>Services are 
usually only instantiated once they are needed.</p><p><span 
class="confluence-embedded-file-wrapper image-center-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image 
image-center" width="500"
  
src="development-dashboard.data/Tapestry_5_Dashboard.png"></span></p><p>&#160;</p><p>Services
 may be builtin, defined, virtual or real.</p><p><strong>Builtin</strong> only 
applies to a few special services that are part of Tapestry 
IoC.</p><p><strong>Defined</strong> services are defined in some module, but 
have not yet been referenced in any way.</p><p><strong>Virtual</strong> 
services have been referenced and have gotten as far as creating a service 
proxy.</p><p><strong>Real</strong> services have had methods invoked, this 
forces the <em>realization</em> of the service which includes instantiating the 
service, injecting dependencies, and decorating with any applicable 
interceptors.</p><h2 id="DevelopmentDashboard-ComponentLibraries">Component 
Libraries</h2><p><span class="confluence-embedded-file-wrapper 
image-center-wrapper confluence-embedded-manual-size"><img 
class="confluence-embedded-image image-center" width="500" 
src="development-dashboard.data/Tapestry_5_Dashboard_-_libs.
 png"></span></p><p>This page gives a summary of all component libraries used 
in the current application.</p></div>
+                <div id="ConfluenceContent"><p>The <strong>development 
dashboard</strong> is a built-in Tapestry page that can help identify and 
resolve problems in your application.</p><p>The dashboard is typically only 
available to requests from localhost (the page is whitelist access only, see <a 
 href="security.html">Security</a>).</p><p><span>Some features of the dashboard 
are only available in development mode.</span></p><p>The dashboard is available 
via the URI "core/t5dashboard", or can be accessed by the <a  
class="external-link" 
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/components/DevTool.html";>DevTool</a>
 component's dropdown menu.</p><p><span>&#160;<span 
class="confluence-embedded-file-wrapper image-center-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image 
image-center" width="500" 
src="development-dashboard.data/Tapestry_5_Dashboard_-_pages.png"></span></span></p><p>By
 default, there are three tabs (this is ext
 ensible).</p><h2 id="DevelopmentDashboard-Pages">Pages</h2><p>The pages tab 
shows what pages are currently loaded into the application. Tapestry only loads 
a page when it is first needed.</p><p>It is possible to clear out Tapestry's 
caches, forcing a reload. You can also run a garbage collection (GC).</p><p>It 
is possible to load any individual page, or attempt to load all pages. This can 
be a good way to see if all pages (and templates) are error free ... loading 
all will catch quite a few potential errors.</p><h2 
id="DevelopmentDashboard-Services">Services</h2><p>When using Tapestry there 
will often be a large number of services defined in the registry; a mix of the 
built-in services provided by the framework and your own.</p><p>Services are 
usually only instantiated once they are needed.</p><p><span 
class="confluence-embedded-file-wrapper image-center-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image 
image-center" width="500" src="development-dashboar
 d.data/Tapestry_5_Dashboard.png"></span></p><p>&#160;</p><p>Services may be 
builtin, defined, virtual or real.</p><p><strong>Builtin</strong> only applies 
to a few special services that are part of Tapestry 
IoC.</p><p><strong>Defined</strong> services are defined in some module, but 
have not yet been referenced in any way.</p><p><strong>Virtual</strong> 
services have been referenced and have gotten as far as creating a service 
proxy.</p><p><strong>Real</strong> services have had methods invoked, this 
forces the <em>realization</em> of the service which includes instantiating the 
service, injecting dependencies, and decorating with any applicable 
interceptors.</p><h2 id="DevelopmentDashboard-ComponentLibraries">Component 
Libraries</h2><p><span class="confluence-embedded-file-wrapper 
image-center-wrapper confluence-embedded-manual-size"><img 
class="confluence-embedded-image image-center" width="500" 
src="development-dashboard.data/Tapestry_5_Dashboard_-_libs.png"></span></p><p>This
 pa
 ge gives a summary of all component libraries used in the current 
application.</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/integration-testing.html
==============================================================================
--- websites/production/tapestry/content/integration-testing.html (original)
+++ websites/production/tapestry/content/integration-testing.html Sun Feb 18 
19:21:00 2018
@@ -109,7 +109,7 @@
 </div>
 
 
-<p>The Tapestry Test Utilities is a small library to make it easier to build 
integration test suites around <a  class="external-link" 
href="http://www.openqa.org/selenium/"; rel="nofollow">Selenium</a> version 
2.14.0.</p><p>The strategy is to start, in-process, a Selenimum Server (which, 
in turn, starts and manages a web browser), a Jetty instance (for the web 
browser to talk to), and a Selenium client (which talks to the 
server).</p><p>The client is able to request URLs, fill in form data, click 
links, and make assertions about output and behavior.</p><h1 
id="IntegrationTesting-Usage">Usage</h1><p>The core part of this library is a 
base class for you to extend your tests classes : <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/SeleniumTestCase.html";>SeleniumTestCase</a>.</p><p>This
 class is responsible for starting an instance of Jetty to server your web 
application, as well as a copy of Selenium Server. It also implements the <a
   class="external-link" 
href="http://release.openqa.org/selenium-remote-control/0.9.0/doc/java/"; 
rel="nofollow">Selenium</a> interface.</p><div 
class="confluence-information-macro confluence-information-macro-note"><span 
class="aui-icon aui-icon-small aui-iconfont-warning 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Before Tapestry 5.2, your class 
should extend <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/AbstractIntegrationTestSuite.html";>AbstractIntegrationTestSuite</a></p></div></div><p>Here's
 an example from one of the Tapestry modules:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Your Integration Test Class : 
SinglePersistenceUnitIntegrationTest.java</b></div><div class="codeContent 
panelContent pdl">
+<p>The Tapestry Test Utilities is a small library to make it easier to build 
integration test suites around <a  class="external-link" 
href="http://www.seleniumhq.org"; rel="nofollow">Selenium</a> version 
2.14.0.</p><p>The strategy is to start, in-process, a Selenium Server (which, 
in turn, starts and manages a web browser), a Jetty instance (for the web 
browser to talk to), and a Selenium client (which talks to the 
server).</p><p>The client is able to request URLs, fill in form data, click 
links, and make assertions about output and behavior.</p><h1 
id="IntegrationTesting-Usage">Usage</h1><p>The core part of this library is a 
base class for you to extend your tests classes : <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/SeleniumTestCase.html";>SeleniumTestCase</a>.</p><p>This
 class is responsible for starting an instance of Jetty to server your web 
application, as well as a copy of Selenium Server. It also implements the <a  
class
 ="external-link" 
href="http://release.openqa.org/selenium-remote-control/0.9.0/doc/java/"; 
rel="nofollow">Selenium</a> interface.</p><div 
class="confluence-information-macro confluence-information-macro-note"><span 
class="aui-icon aui-icon-small aui-iconfont-warning 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Before Tapestry 5.2, your class 
should extend AbstractIntegrationTestSuite</p></div></div><p>Here's an example 
from one of the Tapestry modules:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Your Integration Test Class : 
SinglePersistenceUnitIntegrationTest.java</b></div><div class="codeContent 
panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package org.apache.tapestry5.jpa.integration.app2;
 
 import org.apache.tapestry5.test.SeleniumTestCase;

Modified: websites/production/tapestry/content/ioc.html
==============================================================================
--- websites/production/tapestry/content/ioc.html (original)
+++ websites/production/tapestry/content/ioc.html Sun Feb 18 19:21:00 2018
@@ -118,7 +118,7 @@
 </div>
 
 
-<p>An additional benefit of using IoC is that, by breaking a complex system 
into small pieces, it becomes easier to modify and extend the system, by 
overriding or replacing selected parts of the system.</p><p>The use of IoC in 
Tapestry represents an evolution from Tapestry 3 to Tapestry 4 to Tapestry 5. 
Tapestry 3 did not use IoC, though it included some weaker mechanisms, such as 
extensions, that served a similar purpose. To make large scale changes to the 
behavior of Tapestry 3 required subclassing key classes and overriding 
methods.</p><p>Tapestry 4 introduced the use of the <a  class="external-link" 
href="http://hivemind.apache.org/";>Apache HiveMind</a> IoC container. In fact, 
the HiveMind project was created specifically for use as the IoC container for 
Tapestry 4. Tapestry 4 has met its goals for extensibility and configurability, 
largely because of HiveMind's flexibility.</p><p>Tapestry 5 extends on this, 
replacing HiveMind with a new container specifically build for Tapestry
  5, designed for greater ease of use, expressiveness and performance. HiveMind 
itself has been subsequently shelved; T5 IoC can be considered a streamlined 
and improved HiveMind. And T5 IoC can be used separately from the rest of 
Tapestry!</p><h2 id="IOC-WhyNotSpring?">Why Not Spring?</h2><p><a  
class="external-link" href="http://www.springframework.org"; 
rel="nofollow">Spring</a> is the most successful IoC container project. The 
Spring project combines a very good IoC container, integrated <a  
class="external-link" href="http://www.eclipse.org/aspectj/"; 
rel="nofollow">AspectJ</a> support, and a large number of libraries built on 
top of the container. Spring is an excellent <em>application</em> container, 
but lacks a number of features necessary for a <em>framework</em> 
container:</p><ul><li>Spring beans can be wired together by name (or id), but 
it is not possible to introduce additional naming abstractions. Tapestry 4's 
"infrastructure:" abstraction was the key to allowing easy spo
 t overrides of internal Tapestry services without having to duplicate the 
large web of interrelated services (nearly 200 in Tapestry 
4.0).</li><li>Although Spring allows beans to be intercepted, it does so in the 
form of a new bean, leaving the un-intercepted bean visible (and subject to 
misuse). Tapestry IoC "wraps" the service inside interceptors, preventing 
un-intercepted access to the core service implementation.</li><li>Spring's XML 
configuration files are quite verbose. This has improved with Spring 2.0, but 
still far more verbose that T5 IoC module classes.</li><li>Spring has a simple 
map/list/value configuration scheme, but it is not distributed; it is part of a 
single bean definition. Tapestry 5 IoC allows a service configuration to be 
assembled from multiple modules. This is very important for seamless 
extensibility of the framework, with zero configuration (just drop the module 
into the classpath and everything hooks together).</li></ul><h2 
id="IOC-WhyNotHiveMind?">Why No
 t HiveMind?</h2><p>The difficulty of managing the release schedules of two 
complex frameworks proved to be an issue.</p><p>The use of HiveMind was also 
related to one of the common criticisms of Tapestry 4: startup time. The time 
it took to parse and organize all that XML showed up as several seconds of 
startup time. Creating a streamlined IoC container that is not driven by XML 
has alleviated those issues.</p><p>With the advent of new technologies (in 
particular, JDK 1.5 <a  class="external-link" 
href="http://download.oracle.com/javase/tutorial/java/javaOO/annotations.html"; 
rel="nofollow">Annotations</a> and runtime class generation via <a  
class="external-link" href="http://www.jboss.org/products/javassist"; 
rel="nofollow">Javassist</a>) some of the precepts of HiveMind were undermined. 
That is to say, in HiveMind (as in Spring), all that XML was an awkward way to 
describe a few basic Java operations: instantiating classes and invoking 
methods on those classes (to inject dependenci
 es into the instantiated instances). The central concept in Tapestry IoC is to 
eliminate XML and build an equivalent system around simple objects and 
methods.</p><p>Tapestry IoC also represents many simplifications of HiveMind, 
building on lessons learned from both HiveMind and Tapestry 4. The HiveMind 
project itself is no longer under development, and most of the user base has 
moved to Tapestry 5.</p><h2 id="IOC-WhynotGuice?">Why not Guice?</h2><p><a  
class="external-link" href="http://code.google.com/p/google-guice/"; 
rel="nofollow">Google Guice</a> is a relative newcomer to the IoC landscape. 
Guice and T5 IoC are very close and, in fact, T5 IoC expressly borrows many 
great and innovative ideas from Guice. Guice abandons not only XML but even any 
concept of a service id ... for injection, services are matched by type and 
perhaps filtered based on annotations.</p><p>Guice is still missing some core 
ideas needed in T5 IoC. There's no concept of configurations or anything 
similar. And
  there are limitations on injection based on scope (a request scoped value 
can't be injected into a global scope service; in T5 IoC, scope is internal to 
the proxy and never an issue).</p><h1 id="IOC-Goals">Goals</h1><p>As with 
Tapestry 5 in general, the goal of Tapestry IoC is greater simplicity, greater 
power, and an avoidance of XML.</p><p>Existing IoC containers such as HiveMind 
and Spring typically contain large amounts of XML configuration that exists to 
describe how and when to instantiate a particular JavaBean, and how to provide 
that bean with its dependencies (either by constructor injection, or by 
property injection). Other XML is used to hook objects into some form of life 
cycle ... typically callback methods invoked when the object is instantiated 
and configured, or when it is being discarded.</p><p>The core concept of 
Tapestry IoC is that the Java language itself is the easiest and most succinct 
way to describe object creation and method invocation. Any approximation i
 n XML is ultimately more verbose and unwieldy. As the <a  
href="ioc.html">examples</a> show, a small amount of Java code and a handful of 
naming conventions and annotations is far simpler and easier than a big chunk 
of XML.</p><p>In addition, moving from XML to Java code encourages testing; you 
can unit test the service builder methods of your module class, but you can't 
realistically unit test an XML descriptor.</p><p>Tapestry IoC modules are 
easily packaged into JAR files, supporting zero-configuration usage: just drop 
the JAR onto the classpath.</p><p>Another goal is "developer friendliness". 
This is a true cross-cutting concern, and one not likely to be packaged into an 
aspect any time soon. The Tapestry IoC framework is designed to be easy to use 
and easy to understand. Further, when things go wrong, it actively attempts to 
help you via comprehensive checks and carefully composed error messages. 
Further, all user-visible objects implement a <a  class="external-link" 
href="http:
 //howardlewisship.com/blog/2003/08/importance-of-tostring.html" 
rel="nofollow">reasonable toString() method</a>, to help you understand what's 
going when you inevitably try to figure things out in the debugger.</p><p>In 
terms of building services using Tapestry IoC ... the objective here is 
"lightness", a term borrowed from the board game <a  class="external-link" 
href="http://boardgamegeek.com/game/188"; rel="nofollow">Go</a>. In Go, two 
players place stones on an initially empty board, creating walls to enclose 
territory or eliminate the encroaching stones played by the opponent. The 
winner at the end of the game controls the most territory, and it is the 
constant tension between taking territory and defending existing territory that 
drives the game. In Go, groups of playing stones are "light" (or have "good 
shape") when the minimum number of them control the maximum area on the board. 
Playing "heavy" just gives your opponent a free chance to take control of 
another section of the 
 board.</p><p>In software development, we are also attempting to create complex 
systems from simple pieces, but our tension is derived from the need to add 
functionality balanced against the need to test and maintain existing code. Too 
often in the world of software development, the need to add functionality 
trumps all, and testing and maintenance is deferred ... until too 
late.</p><p>IoC containers in general, and Tapestry IoC very specifically, 
exist to address this issue, to provide the foundations for balancing the need 
to quickly add functionality against the need to test new functionality and 
maintain existing functionality. IoC containers provide the means to break 
large, complex, monolithic blocks into light, small, testable 
pieces.</p><p>When building a registry of services, lightness refers to the 
proper division of responsibility, the separation of concerns, and the limiting 
of dependencies between different parts of the system. This style is often 
called <a  class="extern
 al-link" 
href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/general-formulation.html";
 rel="nofollow">Law of Demeter</a>. Using an IoC container makes it easier to 
embrace this approach, since one critical concern, which objects are 
responsible for instantiating which others, is entirely managed by the 
container. With this life cycle concern removed, it becomes very easy to reduce 
complex chunks of code into small, testable, reusable services.</p><p>"Light" 
means:</p><ul><li>Small interfaces of two or three methods.</li><li>Small 
methods, with two or three parameters (because dependencies are injected in 
behind the scenes, rather than passed into the method).</li><li>Anonymous 
communication via events, rather than explicit method invocations. The service 
implementation can implement an event listener interface.</li></ul><p>See <a  
class="external-link" 
href="http://www.pragmaticprogrammer.com/ppbook/index.shtml"; rel="nofollow">The 
Pragmatic Programmer</a> for m
 ore insights into building solid code.</p><h1 
id="IOC-Terminology">Terminology</h1><p>The basic unit in Tapestry IoC is a 
<strong>service</strong>. A service consists of a <strong>service 
interface</strong> and a <strong>service implementation</strong>. The service 
interface is an ordinary Java interface. The service implementation is a Java 
object that implements the service interface. Often there will only be a single 
service per service interface, but in some situations, there may be many 
different services and service implementations all sharing the same service 
interface.</p><p>Services are identified by a unique id. Typically, a service 
id matches the unqualified name of the service interface, but this is simply a 
convention.</p><div class="confluence-information-macro 
confluence-information-macro-note"><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>The evolutionary direction
  of the Tapestry IoC is to eventually eliminate service ids and work totally 
in terms of service interfaces and marker 
annotations.</p></div></div><p>Services are aggregated into 
<strong>modules</strong>:</p><ul><li>A module is defined by a <strong>module 
class</strong>, a specific class containing a mix of static or instance 
methods, used to define services, decorate them (see below), or contribute to 
service configurations (again, more below).</li><li>Methods of the module class 
define the services provided by the module, and the same methods are 
responsible for instantiating the service implementation.</li></ul><p>The 
methods which define and construct services are called <strong>service builder 
methods</strong>.</p><p>The <strong>registry</strong> is the outside world's 
view of the modules and services. From the registry, it is possible to obtain a 
service, via its unique id or by its service interface. Access by unique id is 
<em>caseless</em> (meaning, a match will be found eve
 n the case of the search key doesn't match the case of the service id 
itself).</p><p>Services may be <strong>decorated</strong> by <strong>service 
decorator methods</strong>. These methods create <strong>interceptor</strong> 
objects that wrap around core service implementations, adding behavior such as 
logging, security access, or transaction management. Interceptors implement the 
same service interface as the service. Control is given over the order in which 
decorators are applied to a service.</p><p>A service may have a 
<strong>configuration</strong>. The configuration is either a map, a 
collection, or an ordered list. The service defines the type of object allowed 
to be contributed into the configuration. The configuration is constructed from 
<strong>contributions</strong> provided by one or more modules. <strong>Service 
contributor methods</strong> are invoked to contribute objects into 
configurations.</p><p>Services are instantiated as needed. In this case, "need" 
translates to
  "when a method of the service is invoked". A service is represented (to the 
outside world, or to other services) as a <strong>proxy</strong> that 
implements the service interface. The first time a method is invoked on the 
proxy, the full service (consisting of the core service implementation wrapped 
with any interceptors) is constructed. This occurs in a completely 
<strong>thread-safe</strong> manner. Just-in-time instantiation allows for more 
complex, more finely grained networks of services, and improves start-up 
time.</p><p>Instantiating a service, injecting dependencies, and decorating the 
service are all parts of service <strong>realization</strong>, the point at 
which a service transitions from virtual (just a proxy) to real (fully 
instantiated and ready to operate).</p><p>Services define a 
<strong>scope</strong> that controls when the service is constructed, as well 
as its visibility. The default scope is <strong>singleton</strong>, meaning a 
single global instance created a
 s needed. Other scopes allow service implementations to be bound to the 
current thread (i.e., the current request in a servlet 
application).</p><p><strong>Dependencies</strong> are other services (or other 
objects) that are needed by a service implementation. These dependencies can be 
<strong>injected</strong> into a service builder method and provided, from 
there, to a service implementation via its constructor, or via methods on the 
service implementation. These may also be referred to as 
<strong>collaborators</strong>, especially in the context of writing unit 
tests.</p><p>The <strong>point of Injection</strong> is a field, method 
parameter, or constructor parameter that receives an injected value. The type 
of service (or other dependency) is determined by the type of the field or 
parameter. Often, annotations further identify what is to be injected, or in 
the case of field injection, that an injection is required.</p><h2 
id="IOC-IoCSubtopics">IoC Subtopics</h2><p></p><ul class="
 childpages-macro"><li><a  href="tapestry-ioc-overview.html">Tapestry IoC 
Overview</a></li><li><a  href="tapestry-ioc-modules.html">Tapestry IoC 
Modules</a></li><li><a  href="defining-tapestry-ioc-services.html">Defining 
Tapestry IOC Services</a></li><li><a  href="service-advisors.html">Service 
Advisors</a></li><li><a  href="tapestry-ioc-decorators.html">Tapestry IoC 
Decorators</a></li><li><a  href="tapestry-ioc-configuration.html">Tapestry IoC 
Configuration</a></li><li><a  href="case-insensitivity.html">Case 
Insensitivity</a></li><li><a  href="autoloading-modules.html">Autoloading 
Modules</a></li><li><a  href="service-implementation-reloading.html">Service 
Implementation Reloading</a></li><li><a  
href="ordering-by-constraints.html">Ordering by Constraints</a></li><li><a  
href="symbols.html">Symbols</a></li><li><a  
href="chainbuilder-service.html">ChainBuilder Service</a></li><li><a  
href="pipelinebuilder-service.html">PipelineBuilder Service</a></li><li><a  
href="shadowbuilder-servi
 ce.html">ShadowBuilder Service</a></li><li><a  
href="strategybuilder-service.html">StrategyBuilder Service</a></li><li><a  
href="injection-in-detail.html">Injection in Detail</a></li><li><a  
href="object-providers.html">Object Providers</a></li><li><a  
href="service-serialization.html">Service Serialization</a></li><li><a  
href="type-coercion.html">Type Coercion</a></li><li><a  
href="starting-the-ioc-registry.html">Starting the IoC Registry</a></li><li><a  
href="registry-startup.html">Registry Startup</a></li><li><a  
href="parallel-execution.html">Parallel Execution</a></li><li><a  
href="logging-in-tapestry.html">Logging in Tapestry</a></li><li><a  
href="using-jsr-330-standard-annotations.html">Using JSR 330 standard 
annotations</a></li><li><a  href="operation-tracker.html">Operation 
Tracker</a></li></ul></div>
+<p>An additional benefit of using IoC is that, by breaking a complex system 
into small pieces, it becomes easier to modify and extend the system, by 
overriding or replacing selected parts of the system.</p><p>The use of IoC in 
Tapestry represents an evolution from Tapestry 3 to Tapestry 4 to Tapestry 5. 
Tapestry 3 did not use IoC, though it included some weaker mechanisms, such as 
extensions, that served a similar purpose. To make large scale changes to the 
behavior of Tapestry 3 required subclassing key classes and overriding 
methods.</p><p>Tapestry 4 introduced the use of the <a  class="external-link" 
href="http://hivemind.apache.org/";>Apache HiveMind</a> IoC container. In fact, 
the HiveMind project was created specifically for use as the IoC container for 
Tapestry 4. Tapestry 4 has met its goals for extensibility and configurability, 
largely because of HiveMind's flexibility.</p><p>Tapestry 5 extends on this, 
replacing HiveMind with a new container specifically build for Tapestry
  5, designed for greater ease of use, expressiveness and performance. HiveMind 
itself has been subsequently shelved; T5 IoC can be considered a streamlined 
and improved HiveMind. And T5 IoC can be used separately from the rest of 
Tapestry!</p><h2 id="IOC-WhyNotSpring?">Why Not Spring?</h2><p><a  
class="external-link" href="http://www.springframework.org"; 
rel="nofollow">Spring</a> is the most successful IoC container project. The 
Spring project combines a very good IoC container, integrated <a  
class="external-link" href="http://www.eclipse.org/aspectj/"; 
rel="nofollow">AspectJ</a> support, and a large number of libraries built on 
top of the container. Spring is an excellent <em>application</em> container, 
but lacks a number of features necessary for a <em>framework</em> 
container:</p><ul><li>Spring beans can be wired together by name (or id), but 
it is not possible to introduce additional naming abstractions. Tapestry 4's 
"infrastructure:" abstraction was the key to allowing easy spo
 t overrides of internal Tapestry services without having to duplicate the 
large web of interrelated services (nearly 200 in Tapestry 
4.0).</li><li>Although Spring allows beans to be intercepted, it does so in the 
form of a new bean, leaving the un-intercepted bean visible (and subject to 
misuse). Tapestry IoC "wraps" the service inside interceptors, preventing 
un-intercepted access to the core service implementation.</li><li>Spring's XML 
configuration files are quite verbose. This has improved with Spring 2.0, but 
still far more verbose that T5 IoC module classes.</li><li>Spring has a simple 
map/list/value configuration scheme, but it is not distributed; it is part of a 
single bean definition. Tapestry 5 IoC allows a service configuration to be 
assembled from multiple modules. This is very important for seamless 
extensibility of the framework, with zero configuration (just drop the module 
into the classpath and everything hooks together).</li></ul><h2 
id="IOC-WhyNotHiveMind?">Why No
 t HiveMind?</h2><p>The difficulty of managing the release schedules of two 
complex frameworks proved to be an issue.</p><p>The use of HiveMind was also 
related to one of the common criticisms of Tapestry 4: startup time. The time 
it took to parse and organize all that XML showed up as several seconds of 
startup time. Creating a streamlined IoC container that is not driven by XML 
has alleviated those issues.</p><p>With the advent of new technologies (in 
particular, JDK 1.5 <a  class="external-link" 
href="http://download.oracle.com/javase/tutorial/java/javaOO/annotations.html"; 
rel="nofollow">Annotations</a> and runtime class generation via <a  
class="external-link" href="http://www.jboss.org/products/javassist"; 
rel="nofollow">Javassist</a>) some of the precepts of HiveMind were undermined. 
That is to say, in HiveMind (as in Spring), all that XML was an awkward way to 
describe a few basic Java operations: instantiating classes and invoking 
methods on those classes (to inject dependenci
 es into the instantiated instances). The central concept in Tapestry IoC is to 
eliminate XML and build an equivalent system around simple objects and 
methods.</p><p>Tapestry IoC also represents many simplifications of HiveMind, 
building on lessons learned from both HiveMind and Tapestry 4. The HiveMind 
project itself is no longer under development, and most of the user base has 
moved to Tapestry 5.</p><h2 id="IOC-WhynotGuice?">Why not Guice?</h2><p><a  
class="external-link" href="http://code.google.com/p/google-guice/"; 
rel="nofollow">Google Guice</a> is a relative newcomer to the IoC landscape. 
Guice and T5 IoC are very close and, in fact, T5 IoC expressly borrows many 
great and innovative ideas from Guice. Guice abandons not only XML but even any 
concept of a service id ... for injection, services are matched by type and 
perhaps filtered based on annotations.</p><p>Guice is still missing some core 
ideas needed in T5 IoC. There's no concept of configurations or anything 
similar. And
  there are limitations on injection based on scope (a request scoped value 
can't be injected into a global scope service; in T5 IoC, scope is internal to 
the proxy and never an issue).</p><h1 id="IOC-Goals">Goals</h1><p>As with 
Tapestry 5 in general, the goal of Tapestry IoC is greater simplicity, greater 
power, and an avoidance of XML.</p><p>Existing IoC containers such as HiveMind 
and Spring typically contain large amounts of XML configuration that exists to 
describe how and when to instantiate a particular JavaBean, and how to provide 
that bean with its dependencies (either by constructor injection, or by 
property injection). Other XML is used to hook objects into some form of life 
cycle ... typically callback methods invoked when the object is instantiated 
and configured, or when it is being discarded.</p><p>The core concept of 
Tapestry IoC is that the Java language itself is the easiest and most succinct 
way to describe object creation and method invocation. Any approximation i
 n XML is ultimately more verbose and unwieldy. As the <a  
href="defining-tapestry-ioc-services.html">Tapestry IOC examples</a> show, a 
small amount of Java code and a handful of naming conventions and annotations 
is far simpler and easier than a big chunk of XML.</p><p>In addition, moving 
from XML to Java code encourages testing; you can unit test the service builder 
methods of your module class, but you can't realistically unit test an XML 
descriptor.</p><p>Tapestry IoC modules are easily packaged into JAR files, 
supporting zero-configuration usage: just drop the JAR onto the 
classpath.</p><p>Another goal is "developer friendliness". This is a true 
cross-cutting concern, and one not likely to be packaged into an aspect any 
time soon. The Tapestry IoC framework is designed to be easy to use and easy to 
understand. Further, when things go wrong, it actively attempts to help you via 
comprehensive checks and carefully composed error messages. Further, all 
user-visible objects implement
  a <a  class="external-link" 
href="https://web.archive.org/web/20041125140446/http://howardlewisship.com/blog/2003/08/importance-of-tostring.html";
 rel="nofollow">reasonable toString() method</a>, to help you understand what's 
going when you inevitably try to figure things out in the debugger.</p><p>In 
terms of building services using Tapestry IoC ... the objective here is 
"lightness", a term borrowed from the board game <a  class="external-link" 
href="http://boardgamegeek.com/game/188"; rel="nofollow">Go</a>. In Go, two 
players place stones on an initially empty board, creating walls to enclose 
territory or eliminate the encroaching stones played by the opponent. The 
winner at the end of the game controls the most territory, and it is the 
constant tension between taking territory and defending existing territory that 
drives the game. In Go, groups of playing stones are "light" (or have "good 
shape") when the minimum number of them control the maximum area on the board. 
Playing "heavy
 " just gives your opponent a free chance to take control of another section of 
the board.</p><p>In software development, we are also attempting to create 
complex systems from simple pieces, but our tension is derived from the need to 
add functionality balanced against the need to test and maintain existing code. 
Too often in the world of software development, the need to add functionality 
trumps all, and testing and maintenance is deferred ... until too 
late.</p><p>IoC containers in general, and Tapestry IoC very specifically, 
exist to address this issue, to provide the foundations for balancing the need 
to quickly add functionality against the need to test new functionality and 
maintain existing functionality. IoC containers provide the means to break 
large, complex, monolithic blocks into light, small, testable 
pieces.</p><p>When building a registry of services, lightness refers to the 
proper division of responsibility, the separation of concerns, and the limiting 
of dependencies 
 between different parts of the system. This style is often called <a  
class="external-link" 
href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/general-formulation.html";
 rel="nofollow">Law of Demeter</a>. Using an IoC container makes it easier to 
embrace this approach, since one critical concern, which objects are 
responsible for instantiating which others, is entirely managed by the 
container. With this life cycle concern removed, it becomes very easy to reduce 
complex chunks of code into small, testable, reusable services.</p><p>"Light" 
means:</p><ul><li>Small interfaces of two or three methods.</li><li>Small 
methods, with two or three parameters (because dependencies are injected in 
behind the scenes, rather than passed into the method).</li><li>Anonymous 
communication via events, rather than explicit method invocations. The service 
implementation can implement an event listener interface.</li></ul><p>See <a  
class="external-link" href="http://www.pragmaticp
 rogrammer.com/ppbook/index.shtml" rel="nofollow">The Pragmatic Programmer</a> 
for more insights into building solid code.</p><h1 
id="IOC-Terminology">Terminology</h1><p>The basic unit in Tapestry IoC is a 
<strong>service</strong>. A service consists of a <strong>service 
interface</strong> and a <strong>service implementation</strong>. The service 
interface is an ordinary Java interface. The service implementation is a Java 
object that implements the service interface. Often there will only be a single 
service per service interface, but in some situations, there may be many 
different services and service implementations all sharing the same service 
interface.</p><p>Services are identified by a unique id. Typically, a service 
id matches the unqualified name of the service interface, but this is simply a 
convention.</p><div class="confluence-information-macro 
confluence-information-macro-note"><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon">
 </span><div class="confluence-information-macro-body"><p>The evolutionary 
direction of the Tapestry IoC is to eventually eliminate service ids and work 
totally in terms of service interfaces and marker 
annotations.</p></div></div><p>Services are aggregated into 
<strong>modules</strong>:</p><ul><li>A module is defined by a <strong>module 
class</strong>, a specific class containing a mix of static or instance 
methods, used to define services, decorate them (see below), or contribute to 
service configurations (again, more below).</li><li>Methods of the module class 
define the services provided by the module, and the same methods are 
responsible for instantiating the service implementation.</li></ul><p>The 
methods which define and construct services are called <strong>service builder 
methods</strong>.</p><p>The <strong>registry</strong> is the outside world's 
view of the modules and services. From the registry, it is possible to obtain a 
service, via its unique id or by its service inte
 rface. Access by unique id is <em>caseless</em> (meaning, a match will be 
found even the case of the search key doesn't match the case of the service id 
itself).</p><p>Services may be <strong>decorated</strong> by <strong>service 
decorator methods</strong>. These methods create <strong>interceptor</strong> 
objects that wrap around core service implementations, adding behavior such as 
logging, security access, or transaction management. Interceptors implement the 
same service interface as the service. Control is given over the order in which 
decorators are applied to a service.</p><p>A service may have a 
<strong>configuration</strong>. The configuration is either a map, a 
collection, or an ordered list. The service defines the type of object allowed 
to be contributed into the configuration. The configuration is constructed from 
<strong>contributions</strong> provided by one or more modules. <strong>Service 
contributor methods</strong> are invoked to contribute objects into configurat
 ions.</p><p>Services are instantiated as needed. In this case, "need" 
translates to "when a method of the service is invoked". A service is 
represented (to the outside world, or to other services) as a 
<strong>proxy</strong> that implements the service interface. The first time a 
method is invoked on the proxy, the full service (consisting of the core 
service implementation wrapped with any interceptors) is constructed. This 
occurs in a completely <strong>thread-safe</strong> manner. Just-in-time 
instantiation allows for more complex, more finely grained networks of 
services, and improves start-up time.</p><p>Instantiating a service, injecting 
dependencies, and decorating the service are all parts of service 
<strong>realization</strong>, the point at which a service transitions from 
virtual (just a proxy) to real (fully instantiated and ready to 
operate).</p><p>Services define a <strong>scope</strong> that controls when the 
service is constructed, as well as its visibility. The defa
 ult scope is <strong>singleton</strong>, meaning a single global instance 
created as needed. Other scopes allow service implementations to be bound to 
the current thread (i.e., the current request in a servlet 
application).</p><p><strong>Dependencies</strong> are other services (or other 
objects) that are needed by a service implementation. These dependencies can be 
<strong>injected</strong> into a service builder method and provided, from 
there, to a service implementation via its constructor, or via methods on the 
service implementation. These may also be referred to as 
<strong>collaborators</strong>, especially in the context of writing unit 
tests.</p><p>The <strong>point of Injection</strong> is a field, method 
parameter, or constructor parameter that receives an injected value. The type 
of service (or other dependency) is determined by the type of the field or 
parameter. Often, annotations further identify what is to be injected, or in 
the case of field injection, that an injec
 tion is required.</p><h2 id="IOC-IoCSubtopics">IoC Subtopics</h2><p></p><ul 
class="childpages-macro"><li><a  href="tapestry-ioc-overview.html">Tapestry IoC 
Overview</a></li><li><a  href="tapestry-ioc-modules.html">Tapestry IoC 
Modules</a></li><li><a  href="defining-tapestry-ioc-services.html">Defining 
Tapestry IOC Services</a></li><li><a  href="service-advisors.html">Service 
Advisors</a></li><li><a  href="tapestry-ioc-decorators.html">Tapestry IoC 
Decorators</a></li><li><a  href="tapestry-ioc-configuration.html">Tapestry IoC 
Configuration</a></li><li><a  href="case-insensitivity.html">Case 
Insensitivity</a></li><li><a  href="autoloading-modules.html">Autoloading 
Modules</a></li><li><a  href="service-implementation-reloading.html">Service 
Implementation Reloading</a></li><li><a  
href="ordering-by-constraints.html">Ordering by Constraints</a></li><li><a  
href="symbols.html">Symbols</a></li><li><a  
href="chainbuilder-service.html">ChainBuilder Service</a></li><li><a  
href="pipelinebuil
 der-service.html">PipelineBuilder Service</a></li><li><a  
href="shadowbuilder-service.html">ShadowBuilder Service</a></li><li><a  
href="strategybuilder-service.html">StrategyBuilder Service</a></li><li><a  
href="injection-in-detail.html">Injection in Detail</a></li><li><a  
href="object-providers.html">Object Providers</a></li><li><a  
href="service-serialization.html">Service Serialization</a></li><li><a  
href="type-coercion.html">Type Coercion</a></li><li><a  
href="starting-the-ioc-registry.html">Starting the IoC Registry</a></li><li><a  
href="registry-startup.html">Registry Startup</a></li><li><a  
href="parallel-execution.html">Parallel Execution</a></li><li><a  
href="logging-in-tapestry.html">Logging in Tapestry</a></li><li><a  
href="using-jsr-330-standard-annotations.html">Using JSR 330 standard 
annotations</a></li><li><a  href="operation-tracker.html">Operation 
Tracker</a></li></ul></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 Sun Feb 18 
19:21:00 2018
@@ -85,7 +85,7 @@ 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 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="tapestry-ioc-modules.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="tapestry-ioc-modules.html">the service 
documentation</a> for more details.</p><h1 
id="TapestryIoCModules-AutobuildingServices">Autobuilding Services</h1><p>Main 
article: <a  href="tapestry-ioc-modules.html">Tapestry IoC Modules</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">
+</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;
@@ -97,7 +97,7 @@ public class MyAppModule
      binder.bind(Indexer.class, IndexerImpl.class);
   }
 }</pre>
-</div></div><p>For more details, see see <a  
href="tapestry-ioc-modules.html">Tapestry IoC Modules</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 servic
 e 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="tapestry-ioc-modules.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">
+</div></div><p class="confluence-link">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 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  
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;
@@ -118,7 +118,7 @@ public class MyAppModule
     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  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="tapestry
 -ioc-modules.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 mark
 er, 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">
+</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</li></ul><p>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-lin
 k" 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!</p><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-i
 oc-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 marke
 r, 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
 {


Reply via email to