From 13ac7196b38534b338ccd4fc95341bb868129369 Mon Sep 17 00:00:00 2001 From: Thomas Trageser Date: Tue, 9 Oct 2012 21:39:01 +0100 Subject: [PATCH] Updated documentation for objects default-init-method and default-destroy-method; add section for InitDestroyObjectPostProcessor --- doc/reference/src/index.xml | 8 +- doc/reference/src/objects.xml | 274 ++++++++++++++++++++++++++-------- 2 files changed, 215 insertions(+), 67 deletions(-) diff --git a/doc/reference/src/index.xml b/doc/reference/src/index.xml index 78a9b353..10a74282 100644 --- a/doc/reference/src/index.xml +++ b/doc/reference/src/index.xml @@ -67,8 +67,8 @@ The Spring.NET Framework Reference Documentation - Version 1.3.2 - Last Updated August 1, 2011 (Latest documentation) + Version 2.0.0 + Last Updated October 10, 2012 (Latest documentation) Mark @@ -118,6 +118,10 @@ Stephen Bohlen + + Thomas + Trageser + The Spring Java Team diff --git a/doc/reference/src/objects.xml b/doc/reference/src/objects.xml index c135e961..94e4848a 100644 --- a/doc/reference/src/objects.xml +++ b/doc/reference/src/objects.xml @@ -29,8 +29,7 @@ This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) - See the section entitled + See the section entitled principle The Spring.Core assembly is the basis for @@ -54,7 +53,7 @@ in this chapter in descriptions of Spring's IoC container. If you are new to Spring.NET or IoC containers in general, you may - want to consider starting with , which + want to consider starting with , which contains a number of introductory level examples that actually demonstrate a lot of what is described in detail below. Don't worry if you don't absorb everything at once... those examples serve only to paint a picture @@ -100,7 +99,7 @@ - + @@ -167,12 +166,12 @@ Spring.NET comes with an XSD schema to make the validation of the XML object definitions a whole lot easier. The XSD document is thoroughly documented so feel free to take a peek inside (see ). The XSD is currently used in the + linkend="springobjectsxsd"/>). The XSD is currently used in the implementation code to validate the XML document. The XSD schema serves a dual purpose in that it also facilitates the editing of XML object definitions inside an XSD aware editor (typically Visual Studio) by providing validation (and Intellisense support in the case of Visual - Studio). You may wish to refer to for more + Studio). You may wish to refer to for more information regarding such integration. @@ -256,7 +255,7 @@ know more about Spring's IResource abstraction to load metadata from other locations as desribed below - and alsoin the chapter + and alsoin the chapter These resources are most frequently files or URLs but can also @@ -270,7 +269,7 @@ referring to a resource that has been embedded inside a .NET assembly, assembly://<AssemblyName>/<NameSpace>/<ResourceName>. The IResource abstraction is explained further in - . + . To create an embedded resource using Visual Studio you must @@ -319,7 +318,7 @@ language="csharp">IApplicationContext ctx = ContextRegistry.GetContext(); The ContextRegistry is used to both instantiate the application context and to perform service locator style access to - other objects. (See for more + other objects. (See for more information). The glue that makes this possible is an implementation of the Base Class Library (BCL) provided IConfigurationSectionHandler interface, namely the @@ -348,12 +347,12 @@ Spring.NET comes with an XSD schema to make the validation of the XML object definitions a whole lot easier. The XSD document is thoroughly documented so feel free to take a peek inside (see ). The XSD is currently used in the + linkend="springobjectsxsd"/>). The XSD is currently used in the implementation code to validate the XML document. The XSD schema serves a dual purpose in that it also facilitates the editing of XML object definitions inside an XSD aware editor (typically Visual Studio) by providing validation (and Intellisense support in the case - of Visual Studio). You may wish to refer to + of Visual Studio). You may wish to refer to for more information regarding such integration. Your XML object definitions can also be defined within the @@ -387,14 +386,14 @@ </configuration> Other options available to structure the configuration files are - described in and - . + described in and + . The IApplicationContext can be configured to register other resource handlers, custom parsers to integrate user-contributed XML schema into the object definitions section, type converters, and define type aliases. These features are discussed in - section + section @@ -524,9 +523,9 @@ IList userList = service.GetUserNames(); Object definition explanation - + - + @@ -540,57 +539,55 @@ IList userList = service.GetUserNames(); type - + id and name - + singleton or prototype - + object properties - + constructor arguments - + autowiring mode - + dependency checking mode - + initialization method - + destruction method - + @@ -764,7 +761,7 @@ IList userList = service.GetUserNames(); For details about the mechanism for supplying arguments to the constructor (if required), and setting object instance properties after the object is constructed, see . + linkend="objects-factory-collaborators"/>. This XML fragment describes an object definition that will be identified by the exampleObject name, instances @@ -837,7 +834,7 @@ IList userList = service.GetUserNames(); For details about the mechanism for supplying (optional) arguments to the factory method and setting object instance properties after it has been returned from the factory, see + linkend="object-factory-properties-detailed"/> @@ -943,7 +940,7 @@ IList userList = service.GetUserNames(); type="GenericsPlay.ExampleGenericObject&lt;GenericDictionary&lt;int , string>>, GenericsPlay" /> or even shorter <object id="myOtherOtherGenericObject" type="GenericsPlay.ExampleGenericObject&lt;MyIntStringDictionary>, GenericsPlay" /> - Refer to for + Refer to for additional information on using type aliases. @@ -1175,11 +1172,11 @@ namespace SimpleApp Type aliases - + - + - + @@ -1395,7 +1392,7 @@ namespace SimpleApp programatically), but rather with an XML definition file which will be converted internally into instances of these classes, and used to load an entire Spring IoC container instance. Refer to for more information regarding + linkend="objects-objects-conversion"/> for more information regarding type conversion, and how you can design your classes to be convertible by Spring.NET. @@ -1910,7 +1907,7 @@ public class MixedIocObject The shortcut forms for value and references are useful to reduce XML verbosity when setting collection properties. See for more information. + linkend="objects-shortcutforms"/> for more information. @@ -1927,7 +1924,7 @@ public class MixedIocObject collection are automaticaly converted from a string to the appropriate type. If you are using your own user-defined type as a generic type parameter you will likely need to register a custom type converter. - Refer to for more + Refer to for more information. The implementations of IList<T> and IDictionary<TKey, TValue> that is created are System.Collections.Generic.List and @@ -2147,7 +2144,7 @@ support=support@example.co.uk // overriden by child familiar bracket [] notation. Spring's XML configuration supports the setting of indexer properties. Overloaded indexers as well as multiparameter indexers are also supported. The - property expression parser described in + property expression parser described in is used to perform the type conversion of the indexer name argument from a string in the XML file to a matching target type. As an example consider the following class public class Person @@ -2568,9 +2565,9 @@ source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventList Autowiring modes - + - + @@ -2734,9 +2731,9 @@ source.OnClick(); // First eventListener1.HandleEvent is invoked, then eventList Dependency checking modes - + - + @@ -3014,7 +3011,7 @@ public class ReplacementComputeValue : IMethodReplacer indicates to Spring.NET that this object is itself a factory and the factories product, not the factory itself, is what will be associated with the object id. Factory objects are discussed further in + linkend="objects-factory-lifecycle-factoryobject"/> Setting a reference to the value of property. @@ -3040,7 +3037,7 @@ public class ReplacementComputeValue : IMethodReplacer Note that nested properties are supported for both instance and class property lookups. The IFactoryObject is discussed more generally in . + linkend="objects-factory-lifecycle-factoryobject"/>. Here's an example where a property path is used against another object instance. In this case, an inner object definition is used and @@ -3163,7 +3160,7 @@ public class ReplacementComputeValue : IMethodReplacer class. Additionally, it is sometimes necessary to invoke a method just to perform some sort of initialization.... while the mechanisms for handling object initialization have yet to be introduced (see ), these + linkend="objects-factory-lifecycle-initializingobject"/>), these mechanisms do not permit any arguments to be passed to any initialization method, and are confined to invoking an initialization method on the object that has just been instantiated by the container. @@ -3392,9 +3389,9 @@ public class MyClassFactory Object Scopes - + - + @@ -3529,7 +3526,7 @@ public class MyClassFactory prototype-scoped object is a replacement for the C# 'new' operator. All lifecycle management past that point must be handled by the client. (For details on the lifecycle of an object in the Spring container, see . + linkend="objects-factory-lifecycle"/>. @@ -3550,7 +3547,7 @@ public class MyClassFactory container is instantiating the singleton object and resolving and injecting its dependencies. If you need a new instance of a prototype object at runtime more than once, see . + linkend="objects-method-injection"/>. @@ -3627,9 +3624,9 @@ public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDispo Built-in <literal>TypeConverters</literal> - + - + @@ -3759,7 +3756,7 @@ public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDispo IApplicationContext is to use the custom configuration section handler TypeConverterSectionHandler This is demonstrated in - section + section An alternate approach, present for legacy reasons in the port of Spring.NET from the Java code base, is to use the object factory @@ -3888,9 +3885,9 @@ public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDispo custom features or other lifecycle behavior Spring.NET does not offer out-of-the-box, you can implement an IObjectPostProcessor yourself. For more information - see. + see. - + IInitializingObject / <literal>init-method</literal> @@ -3983,6 +3980,153 @@ public class AnotherExampleObject : IDisposable } } + + + [PostConstruct] and [Predestroy] attribute driven lifecycle + management + + The InitDestroyAttributeObjectPostProcessor + recognizes lifecycle attributes such as [PostConstruct] and + [PreDestroy]. Introduced in Spring.Net 2.0, the support for these + attributes offers yet another alternative to those described in + initialization callbacks and destruction callbacks. Provided that the + InitDestroyAttributeObjectPostProcessor is + registered within the Spring ApplicationContext, a method carrying one + of these annotations is invoked at the same point in the lifecycle as + the corresponding Spring lifecycle interface method or explicitly + declared callback method. In the example below, the cache will be + pre-populated upon initialization and cleared upon destruction. + + The best way to illustrate the usage of this attribute is with + an example. + + public class MovieLister +{ + [PostConstruct] + public void Init() + { + // do some initialization here + } + + [PreDestroy] + public void Destroy() + { + // do some destruction here + } + + ... +}There is one last little piece of Spring configuration that + is required to actually 'switch on' this behavior. Simply annotating + the methods of your classes is not enough to get this behavior. You + need to enable a component that is aware of the + [PostContrsuct] and [PreDestroy] + attribute and that can process it appropriately. + + This component is the + InitDestroyAttributeObjectPostProcessor class. This + is a special IObjectPostProcessor implementation + that is [PostConstruct]- and + [PreDestroy]-aware and actually provides the + lifecycle logic. It is very easy to configure; simply drop the + following object definition into your Spring XML configuration. + + <object type="Spring.Objects.Factory.Attributes.InitDestroyAttributeObjectPostProcessor, Spring.Core"/>Finally, + you can configure an instance of the + InitDestroyAttributeObjectPostProcessor class to + look for other Attribute types. Simply plug it into the definition of + a InitDestroyAttributeObjectPostProcessor and you + are good to go, see example below: + + <object type="Spring.Objects.Factory.Attributes.InitDestroyAttributeObjectPostProcessor, Spring.Core"> + <property name="InitAttributeType" value="MyApp.Attributes.InitAttribute, MyApp"/> + <property name="DestroyAttributeType" value="MyApp.Attributes.DisposeAttribute, MyApp"/> +</object> + + + + Default initialization and destroy methods + + When you write initialization and destroy method callbacks that + do not use the Spring-specific IInitializingObject and IDisposable + callback interfaces, you typically write methods with names such as + Init(), Initialize(), + Dispose(), and so on. Ideally, the names of such + lifecycle callback methods are standardized across a project so that + all developers use the same method names and ensure + consistency. + + You can configure the Spring container to look for named + initialization and destroy callback method names on every object. This + means that you, as an application developer, can write your + application classes and use an initialization callback called + Init(), without having to configure an + init-method="Init" attribute with each object + definition. The Spring IoC container calls that method when the object + is created (and in accordance with the standard lifecycle callback + contract described previously). This feature also enforces a + consistent naming convention for initialization and destroy method + callbacks. + + Suppose that your initialization callback methods are named + Init() and destroy callback methods are named + Destroy(). Your class will resemble the class in + the following example. + + public class DefaultBlogService : IBlogService +{ + private IBlogDao _blogDao; + + public void Init() + { + if (_blogDao == null) { + throw new InvalidOperationException("The [_blogDao] property must be set."); + } + } + + public void Destroy() + { + // do some destruction work + } +}<objects default-init-method="Init" + defauly-destroy-method="Destroy"> + + <object id="BlogService" class="Examples.DefaultBlogService"> + <property name="_blogDao" ref="BlogDao" /> + </object> + +</objects>The presence of the + default-init-method attribute on the top-level + <objects/> element attribute causes the + Spring IoC container to recognize a method called + Init on objects as the initialization method + callback. When an object is created and assembled, if the object class + has such a method, it is invoked at the appropriate time. If the + object does not have such a method an + ObjectCreationException is thrown. To prevent this + for objects that do not have such a method you need to define an empty + init-method="" and/or + destroy-method="" attributes on the object + itself. + + Where existing object classes already have callback methods that + are named at variance with the convention, you can override the + default by specifying (in XML, that is) the method name using the + init-method and destroy-method + attributes on the <object/> itself. + + The Spring container guarantees that a configured initialization + callback is called immediately after an object is supplied with all + dependencies. Thus the initialization callback is called on the raw + object reference, which means that AOP interceptors and so forth are + not yet applied to the object. A target object is fully created first, + then an AOP proxy (for example) with its interceptor chain is applied. + If the target object and the proxy are defined separately, your code + can even interact with the raw target object, bypassing the proxy. + Hence, it would be inconsistent to apply the interceptors to the Init + method, because doing so would couple the lifecycle of the target + object with its proxy/interceptors and leave strange semantics when + your code interacts directly to the raw target object. + @@ -4011,7 +4155,7 @@ public class AnotherExampleObject : IDisposable IApplicationContext provide access to file resources, publishing application events, and accessing a IMessageSource. These additional features are - described in + described in IObjectNameAware @@ -4435,7 +4579,7 @@ factory.AddObjectPostProcessor(pp); for auto-proxying)”. - + Example: Hello World, IObjectPostProcessor-style @@ -4681,7 +4825,7 @@ cfg.setLocation(new FileSystemResource("ado.properties")); cfg.PostProcessObjectFactory(factory); This + xml:id="objects-factory-autodetect-objectfactorypostprocessors"/>This explicit registration step is not convenient, and this is one of the reasons why the various IApplicationContext implementations are preferred above plain @@ -5055,7 +5199,7 @@ cfg.PostProcessObjectFactory(factory); - + Then you can use ${peggy_name}, ${peggy_age}, @@ -5327,7 +5471,7 @@ joan_age=35 The IFactoryObject concept and interface is used in a number of places within the Spring Framework. Some examples of its use is - described in for the + described in for the PropertyRetrievingFactoryObject and FieldRetrievingFactoryObject. An additional use of creating an custom IFactoryObject implementation is to retrieve an @@ -5365,7 +5509,7 @@ joan_age=35 IConfigurableFactoryObject implementions you - already have examples of in are + already have examples of in are WebServiceProxyFactory. @@ -5459,13 +5603,13 @@ joan_age=35 IObjectFactory capabilities in a lot more depth than the said feature matrix.) - + Feature Matrix - + @@ -5758,7 +5902,7 @@ IApplicationContext context = </configuration> For an example showing type aliases for generic types see . + linkend="objects-creation-generic-types"/>. Another way is to define an object of the type Spring.Objects.Factory.Config.TypeAliasConfigurer @@ -5879,7 +6023,7 @@ IApplicationContext context = Spring.Context.Support.XmlApplicationContext. The name of the context can be used in conjunction with the service locator class, ContextRegistry, discussed in + linkend="objects-servicelocator"/> @@ -5997,7 +6141,7 @@ IApplicationContext context = ever used but provides programmatic ways to add messages to the source. The ResourceSetMessageSource is more interesting and an example is provided for in the distribution and discussed more - extensively in the section. The + extensively in the section. The ResourceSetMessageSource is configured by providing a list of ResourceManagers. When a message code is to be resolved, the list of ResourceManagers is searched to resolve the @@ -6090,7 +6234,7 @@ ctx.GetMessage("error.required", resources in a protocol independent way. The IApplicationContext has a method (GetResource(string)) to take care of this. Refer to - for more information on the string + for more information on the string format to use and the IResource abstraction in general.