diff --git a/doc/reference/src/aop.xml b/doc/reference/src/aop.xml
index 8d49316a..4880569f 100644
--- a/doc/reference/src/aop.xml
+++ b/doc/reference/src/aop.xml
@@ -1571,21 +1571,33 @@ MyInterface myProxyObject2 = (MyInterface)ctx.GetObject("MyObject"); // Will ret
Proxying mechanismsSpring creates AOP proxies built at runtime through the use of the
- TypeBuilder API. Two types of proxies can be created, composition based or
+ TypeBuilder API.
+
+ Two types of proxies can be created, composition based or
inheritance based. If the target object implements at least one interface
then a composition based proxy will be created, otherwise an inheritance
- based proxy will be created. The composition based proxy is implemented by
- creating a type that implements all the interfaces specified on the target
- object. The actual class name of this dynamic type is 'GUID' like. A
- private field holds the target object and the dynamic type implementation
- will first execute any advice before or after making the target object
- method call on the target object. The inheritance based mechanism creates
- a dynamic type where that inherits from the target type. This lets you
- downcast to the target type if needed. Please note that in both cases a
- target method implementation that calls other methods on the target object
- will not be advised. To force inheritance based proxies you should either
- set the ProxyTargetType property of a ProxyFactory or the element
- proxy-target-type when using an AOP schema based configuration.
+ based proxy will be created.
+
+ The composition based proxy is implemented by creating a type that
+ implements all the interfaces specified on the target object. The actual
+ class name of this dynamic type is 'GUID' like. A private field holds the
+ target object and the dynamic type implementation will first execute any
+ advice before or after making the target object method call on the target
+ object.
+
+ The inheritance based mechanism creates a dynamic type where that
+ inherits from the target type. This lets you downcast to the target type
+ if needed. Please note that in both cases a target method implementation
+ that calls other methods on the target object will not be advised. To
+ force inheritance based proxies you should either set the
+ ProxyTargetType to true property of a ProxyFactory
+ or set the XML namespace element proxy-target-type =
+ true when using an AOP schema based configuration.
+
+
+ An important alternative approach to inheritance based proxies is
+ disucssed in the next section.
+ In .NET 2.0 you can define the assembly level attribute,
InternalsVisibleTo, to allow access of internal interfaces/classes to
@@ -1594,6 +1606,46 @@ MyInterface myProxyObject2 = (MyInterface)ctx.GetObject("MyObject"); // Will ret
InternalsVisibleTo("Spring.Proxy")] and [assembly:
InternalsVisibleTo("Spring.DynamicReflection")] to your to AssemblyInfo
file.
+
+
+ InheritanceBasedAopConfigurer
+
+ There is an important limitation in the inheritance based proxy as
+ described above, all methods that manipulate the state of the object
+ should be declared as virtual. Otherwise some method invocations get
+ directed to the private 'target' field member and others to the base
+ class. Winform object are an example of case where this approach does
+ not apply. To address this limitation, a new post-processing mechanism
+ was introduced in version 1.2 that creates a proxy type without the
+ private 'target' field. Interception advice is added directly in the
+ method body before invoking the base class method.
+
+ To use this new inheritance based proxy described in the note
+ above, declare an instance of the InheritanceBasedAopConfigurer, and
+ IObjectFactoryPostProcessor, in yoru configuraiton file. Here is an
+ example.
+
+ <object type="Spring.Aop.Framework.AutoProxy.InheritanceBasedAopConfigurer, Spring.Aop">
+ <property name="ObjectNames">
+ <list>
+ <value>Form*</value>
+ <value>Control*</value>
+ </list>
+ </property>
+ <property name="InterceptorNames">
+ <list>
+ <value>debugInterceptor</value>
+ </list>
+ </property>
+</object>
+
+<object id="debugInterceptor" type="AopPlay.DebugInterceptor, AopPlay"/>
+
+ This configuraiton style is similar to the autoproxy by name
+ approach described here and is
+ particuarly appropriate when you want to apply advice to WinForm
+ classes.
+
diff --git a/doc/reference/src/index.xml b/doc/reference/src/index.xml
index 6f850218..aaceb3de 100644
--- a/doc/reference/src/index.xml
+++ b/doc/reference/src/index.xml
@@ -45,6 +45,7 @@
+
@@ -376,6 +377,9 @@
+
+
+
@@ -390,6 +394,7 @@
&tx-quickstart;
&quartz-quickstart;
&nms-quickstart;
+ &msmq-quickstart;
&wcf-quickstart;
diff --git a/doc/reference/src/msmq.xml b/doc/reference/src/msmq.xml
index c48df4e4..842a1696 100644
--- a/doc/reference/src/msmq.xml
+++ b/doc/reference/src/msmq.xml
@@ -88,6 +88,9 @@
classes to write enterprise MSMQ applications than rolling your own
infrastructure. Feedback and new feature requests are always
welcome.
+
+ The Spring.MsmqQuickstart application located in the examples
+ directory of the distribution shows this functionality in action.
@@ -427,6 +430,10 @@ void Send(MessageQueue messageQueue, Message message);
MessageQueueTemplate. The default value is
MessageQueue.InfiniteTimeout (which is actually
~3 months).
+
+ The XML configuration snippit for defining a MessageQueueTemplate
+ is shown in the previous section and also is located in the MSMQ
+ quickstart application configuraiton file Messaging.xml
@@ -649,7 +656,6 @@ void Send(MessageQueue messageQueue, Message message);
<!-- Delegate to plain .NET object for message handling -->
<object id="messageListenerAdapter" type="Spring.Messaging.Listener.MessageListenerAdapter, Spring.Messaging">
<property name="DefaultResponseQueueName" value="msmqTestResponseQueue"/>
- <property name="MessageConverterObjectName" value="messageConverter"/>
<property name="HandlerObject" ref="simpleHandler"/>
</object>
@@ -779,7 +785,6 @@ void Send(MessageQueue messageQueue, Message message);
<!-- Delegate to plain .NET object for message handling -->
<object id="messageListenerAdapter" type="Spring.Messaging.Listener.MessageListenerAdapter, Spring.Messaging">
<property name="DefaultResponseQueueName" value="msmqTestResponseQueue"/>
- <property name="MessageConverterObjectName" value="messageConverter"/>
<property name="HandlerObject" ref="simpleHandler"/>
</object>
@@ -837,8 +842,11 @@ void Send(MessageQueue messageQueue, Message message);
Commit and Rollback. A specific
implementation is provided that will move the poison message to
another queue after a maximum number of redelivery attempts. See
- SendToQueueExceptionHandler described
- below.
+ SendToQueueExceptionHandler described below.
+ You can set a specific implementation to by setting
+ TransactionalMessageListenerContainer's
+ property
+ MessageTransactionExceptionHandlerThe IMessageTransactionExceptionHandler
implementation SendToQueueExceptionHandler
@@ -946,9 +954,29 @@ void Send(MessageQueue messageQueue, Message message);
The default implementation used in
- MessageQueueTemplate and the message listener is
- an instance of XmlMessageConverter configured with a TargetType to be
- System.String.
+ MessageQueueTemplate and the message listener
+ containers is an instance of XmlMessageConverter configured with a
+ TargetType to be System.String. You specify the types that the
+ XmlMessageConverter can convert though either the array property
+ TargetTypes or
+ TargetTypeNames. Here is an example taken from
+ the QuickStart application
+
+ <object id="xmlMessageConverter" type="Spring.Messaging.Support.Converters.XmlMessageConverter, Spring.Messaging">
+ <property name="TargetTypes">
+ <list>
+ <value>Spring.MsmqQuickStart.Common.Data.TradeRequest, Spring.MsmqQuickStart.Common</value>
+ <value>Spring.MsmqQuickStart.Common.Data.TradeResponse, Spring.MsmqQuickStart.Common</value>
+ <value>System.String, mscorlib</value>
+ </list>
+ </property>
+ </object>
+
+ You can specify other IMessageConverter
+ implementations using the
+ MessageConverterObjectName property on the
+ MessageQueueTemplate and
+ MessageListenerAdapter. Other implementations provided are
@@ -988,7 +1016,7 @@ void Send(MessageQueue messageQueue, Message message);
- interface based message processing
+ Interface based message processing
@@ -1077,12 +1105,12 @@ void Send(MessageQueue messageQueue, Message message);
}
The following configuration shows how to hook up the adapter to
- process incoming MSMQ messages.
+ process incoming MSMQ messages using the default message converter.
+
<!-- Delegate to plain .NET object for message handling -->
<object id="messageListenerAdapter" type="Spring.Messaging.Listener.MessageListenerAdapter, Spring.Messaging">
<property name="DefaultResponseQueueName" value="msmqTestResponseQueue"/>
- <property name="MessageConverterObjectName" value="messageConverter"/>
<property name="HandlerObject" ref="myHandler"/>
</object>
diff --git a/doc/reference/src/nms-quickstart.xml b/doc/reference/src/nms-quickstart.xml
index b31ad002..17fcfe0f 100644
--- a/doc/reference/src/nms-quickstart.xml
+++ b/doc/reference/src/nms-quickstart.xml
@@ -25,6 +25,9 @@
+
+ This example was developed with ActiveMQ 5.1 and the ActiveMQ NMS
+ library with subversion repository number 685750.
@@ -55,7 +58,7 @@
Queues are shown in red and topics in green.
-
+ GatewaysGateways represent the service operation to send a message. The
@@ -89,7 +92,7 @@
purposes.
-
+ Message DataThe TradeRequest object shown above contains
@@ -209,7 +212,7 @@
structure.
-
+ Message HandlersWhen the TradeRequest message is received by
@@ -322,7 +325,7 @@
The implementations of the gateway interfaces inherit from Spring's
helper class NmsGatewaySupport in order to get easy
access to a NmsTemplate for sending. The implementation of the
- IStockService interface is shown below
+ IStockService interface is shown below public class NmsStockServiceGateway : NmsGatewaySupport, IStockService
{
@@ -344,8 +347,14 @@
}
}
- The use of an anonymous delegate allows makes it very easy to apply
- any post processing logic to the converted message.
+ The Send method is using NmsTemplate's
+ ConvertAndSendWithDelegate(object obj,
+ MessagePostProcessorDelegate messagePostProcessorDelegate)
+ method. The anonymous delegate allows you to modify the message
+ properties, such as NMSReplyTo and NMSCorrelationID after the message has
+ been converted from an object but before it has been sent. The use of an
+ anonymous delegate allows makes it very easy to apply any post processing
+ logic to the converted message.The object definition for the
NmsStockServiceGateway is shown below along with
@@ -380,11 +389,11 @@
A similar configuration is used on the server to configure the class
Spring.NmsQuickStart.Server.Gateways.MarketDataServiceGateway
that implements the IMarketDataService
- interface.
+ interface.Since the client is also a consumer of messages, on the topic
APP.STOCK.MARKETDATA and the queue APP.STOCK.JOE (for Trader Joe!), two
- message listener containers are defined as shown below.
+ message listener containers are defined as shown below.
<nms:listener-container connection-factory="ConnectionFactory">
<nms:listener ref="MessageListenerAdapter" destination="APP.STOCK.JOE" />