Modified: 
websites/production/tapestry/content/tapestry-inversion-of-control-faq.html
==============================================================================
--- websites/production/tapestry/content/tapestry-inversion-of-control-faq.html 
(original)
+++ websites/production/tapestry/content/tapestry-inversion-of-control-faq.html 
Mon Feb 19 19:21:08 2018
@@ -77,7 +77,14 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><h2 
id="TapestryInversionofControlFAQ-TapestryInversionofControlContainer">Tapestry 
Inversion of Control Container</h2><p>Main article: <a  
href="tapestry-inversion-of-control-faq.html">Tapestry 
IoC</a></p><p>&#160;</p><div class="aui-label" style="float:right" 
title="Related Articles">
+                <div id="ConfluenceContent"><h1 
id="TapestryInversionofControlFAQ-TapestryInversionofControlContainer">Tapestry 
Inversion of Control Container</h1><p>Main article: <a  
href="tapestry-inversion-of-control-faq.html">Tapestry IoC</a></p><h2 
id="TapestryInversionofControlFAQ-Contents">Contents</h2><p><style 
type="text/css">/*<![CDATA[*/
+div.rbtoc1519068035758 {padding: 0px;}
+div.rbtoc1519068035758 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068035758 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068035758">
+<ul class="toc-indentation"><li><a  
href="#TapestryInversionofControlFAQ-WhydoIneedtodefineaninterfaceformyservices?Whycan'tIjustusetheclassitself?">Why
 do I need to define an interface for my services? Why can't I just use the 
class itself?</a></li><li><a  
href="#TapestryInversionofControlFAQ-Myservicestartsathread;howdoIknowwhentheapplicationisshuttingdown,tostopthatthread?">My
 service starts a thread; how do I know when the application is shutting down, 
to stop that thread?</a></li><li><a  
href="#TapestryInversionofControlFAQ-HowdoImakemyservicestartupwiththerestoftheapplication,ratherthanlazily?">How
 do I make my service startup with the rest of the application, rather than 
lazily?</a></li></ul>
+</div><p>&#160;</p><div class="aui-label" style="float:right" title="Related 
Articles">
 
 
 
@@ -128,7 +135,7 @@
 </div>
 
 
-<h3 
id="TapestryInversionofControlFAQ-WhydoIneedtodefineaninterfaceformyservices?Whycan'tIjustusetheclassitself?">Why
 do I need to define an interface for my services? Why can't I just use the 
class itself?</h3><p>First of all: you can do exactly this, but you lose some 
of the functionality that Tapestry's IoC container provides.</p><p>The reason 
for the split is so that Tapestry can provide functionality for your service 
around the core service implementation. It does this by creating 
<em>proxies</em>: Java classes that implement the service interface. The 
methods of the proxy will ultimately invoke the methods of your service 
implementation.</p><p>One of the primary purposes for proxies is to encapsulate 
the service's life cycle: most services are singletons that are created 
<em>just in time</em>. Just in time means only as soon as you invoke a method. 
What's going on is that the life cycle proxy (the object that gets injected 
into pages, components or other service implementation
 s) checks on each method invocation to see if the actual service exists yet. 
If not, it instantiates and configures it (using proper locking to ensure 
thread safety), then delegates the method invocation to the service.</p><p>If 
you bind a service class (not a service interface and class), then the service 
is fully instantiated the first time it is injected, rather than at that first 
method invocation. Further, you can't use decorations or method advice on such 
a service.</p><p>The final reason for the service interface / implementation 
split is to nudge you towards always coding to an interface, which has manifest 
benefits for code structure, robustness, and testability.</p><h3 
id="TapestryInversionofControlFAQ-Myservicestartsathread;howdoIknowwhentheapplicationisshuttingdown,tostopthatthread?">My
 service starts a thread; how do I know when the application is shutting down, 
to stop that thread?</h3><p>This same concern applies to any long-lived 
resource (a thread, a database connec
 tion, a JMS queue connection) that a service may hold onto. Your code needs to 
know when the application has been undeployed and shutdown. This is actually 
quite easy, by adding some post-injection logic to your implementation 
class.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<h3 
id="TapestryInversionofControlFAQ-WhydoIneedtodefineaninterfaceformyservices?Whycan'tIjustusetheclassitself?">Why
 do I need to define an interface for my services? Why can't I just use the 
class itself?</h3><p>First of all: you can do exactly this, but you lose some 
of the functionality that Tapestry's IoC container provides.</p><p>The reason 
for the split is so that Tapestry can provide functionality for your service 
around the core service implementation. It does this by creating 
<em>proxies</em>: Java classes that implement the service interface. The 
methods of the proxy will ultimately invoke the methods of your service 
implementation.</p><p>One of the primary purposes for proxies is to encapsulate 
the service's life cycle: most services are singletons that are created 
<em>just in time</em>. Just in time means only as soon as you invoke a method. 
What's going on is that the life cycle proxy (the object that gets injected 
into pages, components or other service implementation
 s) checks on each method invocation to see if the actual service exists yet. 
If not, it instantiates and configures it (using proper locking to ensure 
thread safety), then delegates the method invocation to the service.</p><p>If 
you bind a service class (not a service interface and class), then the service 
is fully instantiated the first time it is injected, rather than at that first 
method invocation. Further, you can't use decorations or method advice on such 
a service.</p><p>The final reason for the service interface / implementation 
split is to nudge you towards always coding to an interface, which has manifest 
benefits for code structure, robustness, and testability.</p><h3 
id="TapestryInversionofControlFAQ-Myservicestartsathread;howdoIknowwhentheapplicationisshuttingdown,tostopthatthread?">My
 service starts a thread; how do I know when the application is shutting down, 
to stop that thread?</h3><p>This same concern applies to any long-lived 
resource (a thread, a database connec
 tion, a JMS queue connection) that a service may hold onto. Your code needs to 
know when the application has been undeployed and shutdown. This is actually 
quite easy, by adding some post-injection logic to your implementation 
class.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>MyServiceImpl.java</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: true; theme: Default" 
style="font-size:12px;">public class MyServiceImpl implements MyService
 {
   private boolean shuttingDown;
@@ -157,7 +164,7 @@
   }
 }
 </pre>
-</div></div><p>After Tapestry invokes the constructor of the service 
implementation, and after it performs any field injections, it invokes post 
injection methods. The methods must be public and return void. Parameters to a 
post injection method represent further injections ... in the above example, 
the RegistryShutdownHub is injected into the PostInjection method, since it is 
only used inside that one method.</p><div class="confluence-information-macro 
confluence-information-macro-warning"><span class="aui-icon aui-icon-small 
aui-iconfont-error confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>It is <strong>not</strong> 
recommended that MyServiceImpl take RegistryShutdownHub as a constructor 
parameter and register itself as a listener inside the constructor. Doing so is 
an example of <a  class="external-link" 
href="http://www.ibm.com/developerworks/java/library/j-jtp0618.html"; 
rel="nofollow">unsafe publishing</a>, a remote but potential thr
 ead safety issue.</p></div></div><p>This same technique will work for any kind 
of resource that must be cleaned up or destroyed when the registry shuts 
down.</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>Be careful not to invoke methods 
on any service proxy objects as they will also be shutting down with the 
Registry. A RegistryShutdownListener should not be reliant on anything outside 
of itself.</p></div></div><h3 
id="TapestryInversionofControlFAQ-HowdoImakemyservicestartupwiththerestoftheapplication,ratherthanlazily?">How
 do I make my service startup with the rest of the application, rather than 
lazily?</h3><p>Tapestry services are designed to be <em>lazy</em>; they are 
only fully realized when needed: when the first method on the service interface 
is invoked.</p><p>Sometimes a service does extra work
  that is desirable at application startup: examples may be registering message 
handlers with a JMS implementation, or setting up indexing. Since the service's 
constructor (or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/PostInjection.html";>@PostInjection</a>
 methods) are not invoked until the service is realized.</p><p>The solution is 
the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/EagerLoad.html";>@EagerLoad</a>
 annotation; service implementation classes marked with this annotation are 
loaded when the Registry is first startup, rather than lazily.</p></div>
+</div></div><p>After Tapestry invokes the constructor of the service 
implementation, and after it performs any field injections, it invokes post 
injection methods. The methods must be public and return void. Parameters to a 
post injection method represent further injections ... in the above example, 
the RegistryShutdownHub is injected into the PostInjection method, since it is 
only used inside that one method.</p><div class="confluence-information-macro 
confluence-information-macro-warning"><span class="aui-icon aui-icon-small 
aui-iconfont-error confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>It is <strong>not</strong> 
recommended that MyServiceImpl take RegistryShutdownHub as a constructor 
parameter and register itself as a listener inside the constructor. Doing so is 
an example of <a  class="external-link" 
href="http://www.ibm.com/developerworks/java/library/j-jtp0618.html"; 
rel="nofollow">unsafe publishing</a>, an unlikely but potential 
 thread safety issue.</p></div></div><p>This same technique will work for any 
kind of resource that must be cleaned up or destroyed when the registry shuts 
down.</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>Be careful not to invoke methods 
on any service proxy objects as they will also be shutting down with the 
Registry. A RegistryShutdownListener should not be reliant on anything outside 
of itself.</p></div></div><h3 
id="TapestryInversionofControlFAQ-HowdoImakemyservicestartupwiththerestoftheapplication,ratherthanlazily?">How
 do I make my service startup with the rest of the application, rather than 
lazily?</h3><p>Tapestry services are designed to be <em>lazy</em>; they are 
only fully realized when needed: when the first method on the service interface 
is invoked.</p><p>Sometimes a service does extra w
 ork that is desirable at application startup: examples may be registering 
message handlers with a JMS implementation, or setting up indexing. Since the 
service's constructor (or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/PostInjection.html";>@PostInjection</a>
 methods) are not invoked until the service is realized.</p><p>The solution is 
the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/EagerLoad.html";>@EagerLoad</a>
 annotation; service implementation classes marked with this annotation are 
loaded when the Registry is first startup, rather than lazily.</p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to