You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/07/29 04:32:58 UTC
svn commit: r426747 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
site/apt/ioc/service.apt
Author: hlship
Date: Fri Jul 28 19:32:57 2006
New Revision: 426747
URL: http://svn.apache.org/viewvc?rev=426747&view=rev
Log:
Add some documentation about service lifecycles, including perthread.
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java?rev=426747&r1=426746&r2=426747&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/services/TapestryIOCModule.java Fri Jul 28 19:32:57 2006
@@ -26,7 +26,6 @@
import org.apache.tapestry.ioc.annotations.Id;
import org.apache.tapestry.ioc.annotations.InjectService;
import org.apache.tapestry.ioc.annotations.Lifecycle;
-import org.apache.tapestry.ioc.annotations.Private;
/**
* Defines the base set of services for the Tapestry IOC container.
@@ -65,8 +64,8 @@
}
/**
- * Provides access to additional service lifecycles. Two lifecycles are builtin ("singleton" and
- * "primitive") but additional ones are accessed via this service (and its mapped
+ * Provides access to additional service lifecycles. Two lifecycles are built in ("singleton"
+ * and "primitive") but additional ones are accessed via this service (and its mapped
* configuration).
*/
public ServiceLifecycleSource buildServiceLifecycleSource(
@@ -81,6 +80,7 @@
};
}
+ /** Contributes the "perthread" service lifecycle. */
public void contributeServiceLifecycleSource(
MappedConfiguration<String, ServiceLifecycle> configuration,
@InjectService("ThreadCleanupHub")
Modified: tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt?rev=426747&r1=426746&r2=426747&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/site/apt/ioc/service.apt Fri Jul 28 19:32:57 2006
@@ -81,8 +81,84 @@
Defining Service Lifecycle
- <TBD>
+ Each service has a <lifecycle> that controls when the service implementation is instantiated.
+ There are three build in lifecycles: "singleton", "primitive" and "perthread", but
+ more can be added.
+
+ Service lifecycle is specified using the
+ {{{../apidocs/org/apache/tapestry/ioc/annotations/Lifeycle.html}@Lifecycle annotation}},
+ which is attached to a builder method. When this annotation is not present, the
+ default lifecycle, "singleton" is used.
+* singleton
+
+ Most services use the default lifecycle, "singleton". With this lifecycle a <proxy>
+ is created when the service is first referenced. By reference, we mean any situation in which
+ the service is requested by name, such as using the @InjectService annotation on a
+ service builder method, or by using the
+ {{{../apidocs/org/apache/tapestry/ioc/Registry.html}Registry}} API from outside the
+ container.
+
+ In any case, the service proxy will only create the service implementation when a method
+ on the service interface is invoked. Until then, the service can be thought of as "virtual".
+ As the first method is invoked, the service builder method is invoked, then any service
+ decorations occur. This construction process occurs only once.
+
+* primitive
+
+ A few built-in services use the primitive lifecycle. With primitive, the service
+ is instantiated on first reference, rather than later, on first method invocation,
+ and there is no proxy. Other services, and the outside world,
+
+ An example of this is in the TapestryIOCModule; the ClassFactory service is itself needed
+ to create service proxies, so it must be primitive.
+
++----+
+ @Lifecycle("primitive")
+ public ClassFactory buildClassFactory(Log log)
+ {
+ return new ClassFactoryImpl(log);
+ }
++----+
+
+ Using primitive, it becomes more likely that you'll create a recursive dependency:
+ A service whose builder method invokes methods on the service it is trying to
+ create. Tapestry IoC detects this situation (otherwise there would be an endless loop
+ until the JVM ran out of heap), but it is up to you to avoid this situation, often
+ by splitting a service into two parts. In any case, this situation is slightly easier
+ to slip into when using the primitive service.
+
+ There is rarely a need to use the primitive lifecycle, outside of the internal Tapestry
+ IoC services. The lack of a proxy makes invoking methods on primitive services
+ infinitesmly faster, but this is not something to worry about.
+
+* perthread
+
+ The perthread service lifecycle exists primarily to help multi-threaded servlet applications,
+ though it has other applications.
+
+ With perthread, the service proxy will delegate to a local service instance that is associated
+ with the current thread. Two different threads, invoking methods on the same proxy, will
+ ultimately be invoking methods on two different service instances, each reserved to their own thread.
+
+ This is useful when a service needs to keep request specific state, such as information extracted
+ from the HttpServletRequest (in a web application). The default singleton model would not work
+ in such a multi threaded environment. Using perthread on select services allows state to be isolated
+ to those services. Because the dispatch occurs <inside> the proxy, you can treat the service
+ as a global, like any other.
+
+ You will see that your service builder method is invoked more than once.
+
+ At the end of the request, the Registry's cleanupThread() method is invoked; it will discard
+ any perthread service implementations for the current thread. Generally, this is integrated
+ into the main service loop of the web application's servlet.
+
+ Similar techniques can be used whenever multiple threads are in use, such as processing of
+ messages from a JMS (Java Messaging System) queue, or when using any sort of thread pool.
+ The important thing is to invoke the cleanupThread() method, to discard any request/thread
+ specific information, before processing the next request, message, transaction, or
+ what have you.
+
Injecting Resources
In addition to injecting services, Tapestry will key off of the parameter type to allow