synced AbstractAdvisorAutoProxyCreator hierarchy w/ Spring/J
introduced new "Role" property in IObjectDefinition prepared introducing InfrastructureAdvisorAutoProxyCreator
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
Changes (1.2.0 to 1.2.1)
|
||||
Changes (1.2.0 to 1.2.1 or greater)
|
||||
========================
|
||||
|
||||
Spring.Core
|
||||
-----------
|
||||
|
||||
1. within an ValidationGroup element (<v:group>,<v:exclusive>,..), nested validator elements now must occur after any
|
||||
1. within an ValidationGroup element (<v:group>,<v:exclusive>,..), nested validator elements now must occur after any
|
||||
<v:message>, <v:action> or <v:property> elements. The following was allowed previously, but now will raise a schema
|
||||
validation error:
|
||||
|
||||
|
||||
<v:group ..>
|
||||
<v:validator ...>
|
||||
<v:action ...>
|
||||
|
||||
|
||||
change this to
|
||||
|
||||
|
||||
<v:group ..>
|
||||
<v:action ...>
|
||||
<v:validator ...>
|
||||
@@ -20,17 +21,31 @@ Spring.Core
|
||||
2. XmlReaderContext constructor now requires an IObjectDefinitionFactory to be specified. Thus XmlReaderContext.ObjectDefinitionFactory
|
||||
is read only now.
|
||||
|
||||
3. Changes to the Apache NMS API, which was not yet a public release when included in Spring 1.2.0 made breaking API changes.
|
||||
3. Changes to the Apache NMS API, which was not yet a public release when included in Spring 1.2.0 made breaking API changes.
|
||||
On NmsTemlate,
|
||||
|
||||
1) The property 'byte Priority' was changed to 'MsgPriority Priority'
|
||||
2) The property 'bool Persistent' is no longer part of the NMS API but is still supported in a backward compatible
|
||||
manner by Spring by translation to standard MsgDeliveryMode enumeration values of Persistent and NonPersistent.
|
||||
A new property MsgDelivery has been added. The class, CachedMessageProducer, which is unlikely to be use by
|
||||
A new property MsgDelivery has been added. The class, CachedMessageProducer, which is unlikely to be use by
|
||||
end users, was directly upgraded to the latest API without any backwards compatibility support.
|
||||
|
||||
Spring.Aop
|
||||
----------
|
||||
|
||||
1. AbstractAutoProxyCreator.FindEligibleAdvisors(Type) changed to
|
||||
AbstractAutoProxyCreator.FindEligibleAdvisors(Type, Name)
|
||||
|
||||
|
||||
Changes (1.2 RC1 to 1.2.0 or greater)
|
||||
=====================================
|
||||
|
||||
none
|
||||
|
||||
|
||||
|
||||
Changes (1.1.2 to 1.2 RC1 or greater)
|
||||
=====================================
|
||||
|
||||
Spring.Core
|
||||
-----------
|
||||
|
||||
@@ -35,21 +35,18 @@ namespace Spring.Aop.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class for handling registration of auto-proxy creators used internally by the
|
||||
/// <code>aop</code> namespace tags.
|
||||
/// <code>aop</code> and <code>tx</code> namespace tags.
|
||||
/// </summary>
|
||||
/// <author>Rob Harrop</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
public class AopNamespaceUtils
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The object name of the internally managed auto-proxy creator.
|
||||
/// </summary>
|
||||
public const string AUTO_PROXY_CREATOR_OBJECT_NAME =
|
||||
"Spring.Aop.Config.InternalAutoProxyCreator";
|
||||
|
||||
|
||||
public static readonly string AUTO_PROXY_CREATOR_OBJECT_NAME = "Spring.Aop.Config.InternalAutoProxyCreator";
|
||||
|
||||
/// <summary>
|
||||
/// Registers the auto proxy creator if necessary.
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using Spring.Collections;
|
||||
using Spring.Util;
|
||||
@@ -217,8 +218,36 @@ namespace Spring.Aop.Framework
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the pointcut can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(
|
||||
IPointcut pointcut, Type targetType, Type[] proxyInterfaces)
|
||||
public static bool CanApply(IPointcut pointcut, Type targetType, Type[] proxyInterfaces)
|
||||
{
|
||||
return CanApply(pointcut, targetType, proxyInterfaces, false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="pointcut"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out a
|
||||
/// pointcut for a class.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Invoking this method with a <paramref name="targetType"/> that is
|
||||
/// an interface type will always yield a <see langword="false"/>
|
||||
/// return value.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="pointcut">The pointcut being tested.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <param name="hasIntroductions">whether or not the advisor chain for the target object includes any introductions.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the pointcut can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IPointcut pointcut, Type targetType, Type[] proxyInterfaces, bool hasIntroductions)
|
||||
{
|
||||
if (!pointcut.TypeFilter.Matches(targetType))
|
||||
{
|
||||
@@ -266,8 +295,32 @@ namespace Spring.Aop.Framework
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advisor can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(
|
||||
IAdvisor advisor, Type targetType, Type[] proxyInterfaces)
|
||||
public static bool CanApply(IAdvisor advisor, Type targetType, Type[] proxyInterfaces)
|
||||
{
|
||||
return CanApply(advisor, targetType, proxyInterfaces, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can the supplied <paramref name="advisor"/> apply at all on the
|
||||
/// supplied <paramref name="targetType"/>?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an important test as it can be used to optimize out an
|
||||
/// advisor for a class.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="advisor">The advisor to check.</param>
|
||||
/// <param name="targetType">The class being tested.</param>
|
||||
/// <param name="proxyInterfaces">
|
||||
/// The interfaces being proxied. If <see langword="null"/>, all
|
||||
/// methods on a class may be proxied.
|
||||
/// </param>
|
||||
/// <param name="hasIntroductions">whether or not the advisor chain for the target object includes any introductions.</param>
|
||||
/// <returns>
|
||||
/// <see langword="true"/> if the advisor can apply on any method.
|
||||
/// </returns>
|
||||
public static bool CanApply(IAdvisor advisor, Type targetType, Type[] proxyInterfaces, bool hasIntroductions)
|
||||
{
|
||||
if (advisor is IIntroductionAdvisor)
|
||||
{
|
||||
@@ -276,7 +329,7 @@ namespace Spring.Aop.Framework
|
||||
else if (advisor is IPointcutAdvisor)
|
||||
{
|
||||
IPointcutAdvisor pca = (IPointcutAdvisor)advisor;
|
||||
return CanApply(pca.Pointcut, targetType, proxyInterfaces);
|
||||
return CanApply(pca.Pointcut, targetType, proxyInterfaces, hasIntroductions);
|
||||
}
|
||||
// no pointcut specified so assume it applies...
|
||||
return true;
|
||||
|
||||
@@ -22,17 +22,19 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Common.Logging;
|
||||
using Spring.Aop.Framework.DynamicProxy;
|
||||
using Spring.Core;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Util;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Aop.Framework.AutoProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract IOBjectPostProcessor implementation that creates AOP proxies.
|
||||
/// Abstract IObjectPostProcessor implementation that creates AOP proxies.
|
||||
/// This class is completely generic; it contains no special code to handle
|
||||
/// any particular aspects, such as pooling aspects.
|
||||
/// </summary>
|
||||
@@ -50,9 +52,21 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// </remarks>
|
||||
/// <seealso cref="Spring.Aop.Framework.AutoProxy.AbstractAdvisorAutoProxyCreator.FindCandidateAdvisors"/>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public abstract class AbstractAdvisorAutoProxyCreator : AbstractAutoProxyCreator
|
||||
{
|
||||
private readonly ILog Log;
|
||||
private ObjectFactoryAdvisorRetrievalHelper _advisorRetrievalHelper;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize
|
||||
/// </summary>
|
||||
protected AbstractAdvisorAutoProxyCreator()
|
||||
{
|
||||
Log = LogManager.GetLogger(this.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We override this method to ensure that all candidate advisors are materialized
|
||||
/// under a stack trace including this object. Otherwise, the dependencies won't
|
||||
@@ -60,85 +74,139 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// </summary>
|
||||
public override IObjectFactory ObjectFactory
|
||||
{
|
||||
//TODO investigate override...
|
||||
set
|
||||
{
|
||||
base.ObjectFactory = value;
|
||||
if (!(value is IConfigurableListableObjectFactory))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Can not use AdvisorAutoProxyCreator without a ConfigurableListableObjectFactory");
|
||||
throw new InvalidOperationException("Can not use AdvisorAutoProxyCreator without a ConfigurableListableObjectFactory");
|
||||
}
|
||||
InitObjectFactory((IConfigurableListableObjectFactory) value);
|
||||
}
|
||||
get { return base.ObjectFactory; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An new <see cref="IConfigurableListableObjectFactory"/> was set. Initialize this creator instance
|
||||
/// according to the specified object factory.
|
||||
/// </summary>
|
||||
/// <param name="objectFactory"></param>
|
||||
protected virtual void InitObjectFactory(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
_advisorRetrievalHelper = new ObjectFactoryAdvisorRetrievalHelperAdapter(this, objectFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return whether the given object is to be proxied, what additional
|
||||
/// advices (e.g. AOP Alliance interceptors) and advisors to apply.
|
||||
/// </summary>
|
||||
/// <param name="objType">the new object instance</param>
|
||||
/// <param name="name">the name of the object</param>
|
||||
/// <param name="customTargetSource">targetSource returned by TargetSource property:
|
||||
/// may be ignored. Will be null unless a custom target source is in use.</param>
|
||||
/// <returns>
|
||||
/// an array of additional interceptors for the particular object;
|
||||
/// or an empty array if no additional interceptors but just the common ones;
|
||||
/// or null if no proxy at all, not even with the common interceptors.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// <p>The previous name of this method was "GetInterceptorAndAdvisorForObject".
|
||||
/// <p>The previous targetName of this method was "GetInterceptorAndAdvisorForObject".
|
||||
/// It has been renamed in the course of general terminology clarification
|
||||
/// in Spring 1.1. An AOP Alliance Interceptor is just a special form of
|
||||
/// Advice, so the generic Advice term is preferred now.</p>
|
||||
/// <p>The third parameter, customTargetSource, is new in Spring 1.1;
|
||||
/// add it to existing implementations of this method.</p>
|
||||
/// </remarks>
|
||||
protected override object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource)
|
||||
/// </remarks>
|
||||
/// <param name="targetType">the type of the target object</param>
|
||||
/// <param name="targetName">the name of the target object</param>
|
||||
/// <param name="customTargetSource">targetSource returned by TargetSource property:
|
||||
/// may be ignored. Will be null unless a custom target source is in use.</param>
|
||||
/// <returns>
|
||||
/// an array of additional interceptors for the particular object;
|
||||
/// or an empty array if no additional interceptors but just the common ones;
|
||||
/// or null if no proxy at all, not even with the common interceptors.
|
||||
/// </returns>
|
||||
protected override object[] GetAdvicesAndAdvisorsForObject(Type targetType, string targetName, ITargetSource customTargetSource)
|
||||
{
|
||||
IList advisors = FindEligibleAdvisors(objType);
|
||||
IList advisors = FindEligibleAdvisors(targetType, targetName);
|
||||
if (advisors.Count == 0)
|
||||
{
|
||||
return DO_NOT_PROXY;
|
||||
}
|
||||
advisors = SortAdvisors(advisors);
|
||||
if (advisors is ArrayList)
|
||||
return ((ArrayList) advisors).ToArray();
|
||||
else
|
||||
{
|
||||
return advisors as object[];
|
||||
}
|
||||
return (object[]) CollectionUtils.ToArray(advisors, typeof (object));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all eligible advices and for autoproxying this class.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns>the empty list, not null, if there are no pointcuts or interceptors</returns>
|
||||
protected IList FindEligibleAdvisors(Type type)
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>
|
||||
/// the empty list, not null, if there are no pointcuts or interceptors.
|
||||
/// The by-order sorted list of advisors otherwise
|
||||
/// </returns>
|
||||
protected IList FindEligibleAdvisors(Type targetType, string targetName)
|
||||
{
|
||||
IList candidateAdvisors = FindCandidateAdvisors();
|
||||
IList eligibleAdvisors = new ArrayList();
|
||||
for (int i = 0; i < candidateAdvisors.Count; i++)
|
||||
{
|
||||
IAdvisor candidate = (IAdvisor) candidateAdvisors[i];
|
||||
if (AopUtils.CanApply(candidate, type, null))
|
||||
{
|
||||
eligibleAdvisors.Add(candidate);
|
||||
if (logger.IsInfoEnabled)
|
||||
{
|
||||
logger.Info(string.Format("Candidate advisor [{0}] accepted for type [{1}]", candidate, type.ToString()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.IsInfoEnabled)
|
||||
{
|
||||
logger.Info(string.Format("Candidate advisor [{0}] rejected for type [{1}]", candidate, type.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
IList candidateAdvisors = FindCandidateAdvisors(targetType, targetName);
|
||||
IList eligibleAdvisors = FindAdvisorsThatCanApply(candidateAdvisors, targetType, targetName);
|
||||
|
||||
ExtendAdvisors(eligibleAdvisors, targetType, targetName);
|
||||
eligibleAdvisors = SortAdvisors(eligibleAdvisors);
|
||||
|
||||
return eligibleAdvisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all possible advisor candidates to use in auto-proxying
|
||||
/// </summary>
|
||||
/// <param name="targetType">the type of the object to be advised</param>
|
||||
/// <param name="targetName">the name of the object to be advised</param>
|
||||
/// <returns>the list of candidate advisors</returns>
|
||||
protected virtual IList FindCandidateAdvisors(Type targetType, string targetName)
|
||||
{
|
||||
return _advisorRetrievalHelper.FindAdvisorObjects(targetType, targetName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// From the given list of candidate advisors, select the ones that are applicable
|
||||
/// to the given target specified by targetType and name.
|
||||
/// </summary>
|
||||
/// <param name="candidateAdvisors">the list of candidate advisors to date</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
/// <returns>the list of applicable advisors</returns>
|
||||
protected virtual IList FindAdvisorsThatCanApply(IList candidateAdvisors, Type targetType, string targetName)
|
||||
{
|
||||
if (candidateAdvisors.Count==0)
|
||||
{
|
||||
return candidateAdvisors;
|
||||
}
|
||||
|
||||
ArrayList eligibleAdvisors = new ArrayList();
|
||||
foreach(IAdvisor candidate in candidateAdvisors)
|
||||
{
|
||||
if (candidate is IIntroductionAdvisor && AopUtils.CanApply(candidate, targetType, null))
|
||||
{
|
||||
if (logger.IsInfoEnabled)
|
||||
{
|
||||
logger.Info(string.Format("Candidate advisor [{0}] accepted for targetType [{1}]", candidate, targetType));
|
||||
}
|
||||
eligibleAdvisors.Add(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasIntroductions = eligibleAdvisors.Count > 0;
|
||||
foreach(IAdvisor candidate in candidateAdvisors)
|
||||
{
|
||||
if (candidate is IIntroductionAdvisor) continue;
|
||||
|
||||
if (AopUtils.CanApply(candidate, targetType, null, hasIntroductions))
|
||||
{
|
||||
if (logger.IsInfoEnabled)
|
||||
{
|
||||
logger.Info(string.Format("Candidate advisor [{0}] accepted for targetType [{1}]", candidate, targetType));
|
||||
}
|
||||
eligibleAdvisors.Add(candidate);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logger.IsInfoEnabled)
|
||||
{
|
||||
logger.Info(string.Format("Candidate advisor [{0}] rejected for targetType [{1}]", candidate, targetType));
|
||||
}
|
||||
}
|
||||
}
|
||||
return eligibleAdvisors;
|
||||
}
|
||||
|
||||
|
||||
@@ -147,8 +215,13 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// </summary>
|
||||
/// <param name="advisors">The advisors.</param>
|
||||
/// <returns></returns>
|
||||
protected IList SortAdvisors(IList advisors)
|
||||
protected virtual IList SortAdvisors(IList advisors)
|
||||
{
|
||||
if (advisors.Count==0)
|
||||
{
|
||||
return advisors;
|
||||
}
|
||||
|
||||
if (advisors is ArrayList)
|
||||
((ArrayList) advisors).Sort(new OrderComparator());
|
||||
else if (advisors is Array)
|
||||
@@ -156,10 +229,43 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
return advisors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find all candidate advisors to use in auto-proxying.
|
||||
/// </summary>
|
||||
/// <returns>list of Advisors</returns>
|
||||
protected abstract IList FindCandidateAdvisors();
|
||||
/// <summary>
|
||||
/// Extension hook that subclasses can override to register additional advisors,
|
||||
/// given the sorted advisors obtained to date.<br/>
|
||||
/// The default implementation does nothing.<br/>
|
||||
/// Typically used to add advisors that expose contextual information required by some of the later advisors.
|
||||
/// </summary>
|
||||
/// <param name="advisors">Advisors that have already been identified as applying to a given object</param>
|
||||
/// <param name="objectType">the type of the object to be advised</param>
|
||||
/// <param name="objectName">the name of the object to be advised</param>
|
||||
protected virtual void ExtendAdvisors(IList advisors, Type objectType, string objectName)
|
||||
{}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the given advisor is eligible for the specified target. The default implementation
|
||||
/// always returns true.
|
||||
/// </summary>
|
||||
/// <param name="advisorName">the advisor name</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
protected virtual bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private class ObjectFactoryAdvisorRetrievalHelperAdapter : ObjectFactoryAdvisorRetrievalHelper
|
||||
{
|
||||
private readonly AbstractAdvisorAutoProxyCreator _owner;
|
||||
|
||||
public ObjectFactoryAdvisorRetrievalHelperAdapter(AbstractAdvisorAutoProxyCreator owner, IConfigurableListableObjectFactory owningFactory) : base(owningFactory)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
protected override bool IsEligibleObject(string advisorName, Type objectType, string objectName)
|
||||
{
|
||||
return _owner.IsEligibleAdvisorObject(advisorName, objectType, objectName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -355,10 +355,10 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// Sometimes we need to be able to avoid this happening if it will lead to
|
||||
/// a circular reference. This implementation returns false.
|
||||
/// </summary>
|
||||
/// <param name="objectType">the type of the object</param>
|
||||
/// <param name="objectName">the name of the object</param>
|
||||
/// <param name="targetType">the type of the object</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <returns>if remarkable to skip</returns>
|
||||
protected virtual bool ShouldSkip(Type objectType, string objectName)
|
||||
protected virtual bool ShouldSkip(Type targetType, string targetName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -434,32 +434,32 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// advices (e.g. AOP Alliance interceptors) and advisors to apply.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>The previous name of this method was "GetInterceptorAndAdvisorForObject".
|
||||
/// <p>The previous targetName of this method was "GetInterceptorAndAdvisorForObject".
|
||||
/// It has been renamed in the course of general terminology clarification
|
||||
/// in Spring 1.1. An AOP Alliance Interceptor is just a special form of
|
||||
/// Advice, so the generic Advice term is preferred now.</p>
|
||||
/// <p>The third parameter, customTargetSource, is new in Spring 1.1;
|
||||
/// add it to existing implementations of this method.</p>
|
||||
/// </remarks>
|
||||
/// <param name="objType">the new object instance</param>
|
||||
/// <param name="name">the name of the object</param>
|
||||
/// <param name="targetType">the new object instance</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <param name="customTargetSource">targetSource returned by TargetSource property:
|
||||
/// may be ignored. Will be null unless a custom target source is in use.</param>
|
||||
/// <returns>an array of additional interceptors for the particular object;
|
||||
/// or an empty array if no additional interceptors but just the common ones;
|
||||
/// or null if no proxy at all, not even with the common interceptors.</returns>
|
||||
protected abstract object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource);
|
||||
protected abstract object[] GetAdvicesAndAdvisorsForObject(Type targetType, string targetName, ITargetSource customTargetSource);
|
||||
|
||||
/// <summary>
|
||||
/// Create an AOP proxy for the given object.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="objectName">The name of the object.</param>
|
||||
/// <param name="targetType">Type of the object.</param>
|
||||
/// <param name="targetName">The name of the object.</param>
|
||||
/// <param name="specificInterceptors">The set of interceptors that is specific to this
|
||||
/// object (may be empty but not null)</param>
|
||||
/// <param name="targetSource">The target source for the proxy, already pre-configured to access the object.</param>
|
||||
/// <returns>The AOP Proxy for the object.</returns>
|
||||
protected virtual object CreateProxy(Type objectType, string objectName, object[] specificInterceptors, ITargetSource targetSource)
|
||||
protected virtual object CreateProxy(Type targetType, string targetName, object[] specificInterceptors, ITargetSource targetSource)
|
||||
{
|
||||
ProxyFactory proxyFactory = CreateProxyFactory();
|
||||
// copy our properties (proxyTargetClass) inherited from ProxyConfig
|
||||
@@ -472,7 +472,7 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
{
|
||||
// Must allow for introductions; can't just set interfaces to
|
||||
// the target's interfaces only.
|
||||
Type[] targetInterfaceTypes = AopUtils.GetAllInterfacesFromType(objectType);
|
||||
Type[] targetInterfaceTypes = AopUtils.GetAllInterfacesFromType(targetType);
|
||||
foreach (Type interfaceType in targetInterfaceTypes)
|
||||
{
|
||||
proxyFactory.AddInterface(interfaceType);
|
||||
@@ -480,7 +480,7 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
}
|
||||
|
||||
|
||||
IAdvisor[] advisors = BuildAdvisors(objectName, specificInterceptors);
|
||||
IAdvisor[] advisors = BuildAdvisors(targetName, specificInterceptors);
|
||||
|
||||
foreach (IAdvisor advisor in advisors)
|
||||
{
|
||||
@@ -513,11 +513,11 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// Determines the advisors for the given object, including the specific interceptors
|
||||
/// as well as the common interceptor, all adapted to the Advisor interface.
|
||||
/// </summary>
|
||||
/// <param name="objectName">The name of the object.</param>
|
||||
/// <param name="targetName">The name of the object.</param>
|
||||
/// <param name="specificInterceptors">The set of interceptors that is specific to this
|
||||
/// object (may be empty, but not null)</param>
|
||||
/// <returns>The list of Advisors for the given object</returns>
|
||||
protected virtual IAdvisor[] BuildAdvisors(string objectName, object[] specificInterceptors)
|
||||
protected virtual IAdvisor[] BuildAdvisors(string targetName, object[] specificInterceptors)
|
||||
{
|
||||
// handle prototypes correctly
|
||||
IAdvisor[] commonInterceptors = ResolveInterceptorNames();
|
||||
@@ -542,7 +542,7 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
{
|
||||
int nrOfCommonInterceptors = commonInterceptors != null ? commonInterceptors.Length : 0;
|
||||
int nrOfSpecificInterceptors = specificInterceptors != null ? specificInterceptors.Length : 0;
|
||||
logger.Info(string.Format("Creating implicit proxy for object '{0}' with {1} common interceptors and {2} specific interceptors", objectName, nrOfCommonInterceptors, nrOfSpecificInterceptors));
|
||||
logger.Info(string.Format("Creating implicit proxy for object '{0}' with {1} common interceptors and {2} specific interceptors", targetName, nrOfCommonInterceptors, nrOfSpecificInterceptors));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,12 +39,12 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// <summary>
|
||||
///Overridden to call <see cref="IsEligibleForProxying"/>.
|
||||
/// </summary>
|
||||
/// <param name="objectType">the type of the object</param>
|
||||
/// <param name="objectName">the name of the object</param>
|
||||
/// <param name="targetType">the type of the object</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <returns>if remarkable to skip</returns>
|
||||
protected override bool ShouldSkip( Type objectType, string objectName )
|
||||
protected override bool ShouldSkip( Type targetType, string targetName )
|
||||
{
|
||||
bool shouldSkip = !IsEligibleForProxying( objectType, objectName );
|
||||
bool shouldSkip = !IsEligibleForProxying( targetType, targetName );
|
||||
return shouldSkip;
|
||||
}
|
||||
|
||||
@@ -54,14 +54,14 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// <remarks>
|
||||
/// Whether an object shall be proxied or not is determined by the result of <see cref="IsEligibleForProxying"/>.
|
||||
/// </remarks>
|
||||
/// <param name="objType">ingored</param>
|
||||
/// <param name="name">ignored</param>
|
||||
/// <param name="targetType">ingored</param>
|
||||
/// <param name="targetName">ignored</param>
|
||||
/// <param name="customTargetSource">ignored</param>
|
||||
/// <returns>
|
||||
/// Always <see cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/> to indicate, that the object shall be proxied.
|
||||
/// </returns>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS"/>
|
||||
protected override object[] GetAdvicesAndAdvisorsForObject( Type objType, string name, ITargetSource customTargetSource )
|
||||
protected override object[] GetAdvicesAndAdvisorsForObject( Type targetType, string targetName, ITargetSource customTargetSource )
|
||||
{
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
}
|
||||
@@ -72,10 +72,10 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// <remarks>
|
||||
/// Override this method to allow or reject proxying for the given object.
|
||||
/// </remarks>
|
||||
/// <param name="objType">the object's type</param>
|
||||
/// <param name="name">the name of the object</param>
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.ShouldSkip"/>
|
||||
/// <returns>whether the given object shall be proxied.</returns>
|
||||
protected abstract bool IsEligibleForProxying( Type objType, string name );
|
||||
protected abstract bool IsEligibleForProxying( Type targetType, string targetName );
|
||||
}
|
||||
}
|
||||
@@ -61,15 +61,15 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines, whether the given object shall be proxied by matching <paramref name="objType"/> against <see cref="AttributeTypes"/>.
|
||||
/// Determines, whether the given object shall be proxied by matching <paramref name="targetType"/> against <see cref="AttributeTypes"/>.
|
||||
/// </summary>
|
||||
/// <param name="objType">the object's type</param>
|
||||
/// <param name="name">the name of the object</param>
|
||||
protected override bool IsEligibleForProxying( Type objType, string name )
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
protected override bool IsEligibleForProxying( Type targetType, string targetName )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(this.AttributeTypes, "AttributeTypes");
|
||||
|
||||
bool shallProxy = IsAnnotatedWithAnyOfAttribute( objType, this.AttributeTypes, this.CheckInherited );
|
||||
bool shallProxy = IsAnnotatedWithAnyOfAttribute( targetType, this.AttributeTypes, this.CheckInherited );
|
||||
return shallProxy;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,7 @@
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Config;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -36,16 +34,15 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// </summary>
|
||||
/// <author>Rod Johnson</author>
|
||||
/// <author>Adhari C Mahendra (.NET)</author>
|
||||
public class DefaultAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator, IObjectNameAware, IInitializingObject
|
||||
/// <author>Erich Eichinger (.NET)</author>
|
||||
public class DefaultAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator, IObjectNameAware
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Separator between prefix and remainder of object name
|
||||
/// </summary>
|
||||
public static readonly string SEPARATOR = ".";
|
||||
private bool usePrefix;
|
||||
private string advisorObjectNamePrefix;
|
||||
private IList advisors;
|
||||
|
||||
#region Properties
|
||||
|
||||
@@ -72,126 +69,45 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
set { advisorObjectNamePrefix = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IObjectNameAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Set the name of the object in the object factory that created this object.
|
||||
/// </summary>
|
||||
/// <value>The name of the object in the factory.</value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="T:Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="M:Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public string ObjectName
|
||||
{
|
||||
set
|
||||
{
|
||||
// If no infrastructure object name prefix has been set, override it.
|
||||
if (advisorObjectNamePrefix == null)
|
||||
{
|
||||
advisorObjectNamePrefix = value + SEPARATOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Find all candidate advices to use in auto proxying.
|
||||
/// </summary>
|
||||
/// <returns>list of Advice</returns>
|
||||
protected override IList FindCandidateAdvisors()
|
||||
{
|
||||
if (advisors == null)
|
||||
{
|
||||
throw new InvalidOperationException("Must not be called before AfterPropertiesSet()");
|
||||
}
|
||||
if (logger.IsDebugEnabled)
|
||||
{
|
||||
logger.Debug(string.Format("returning available advisors"));
|
||||
}
|
||||
return advisors;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the given advisor is eligible for the specified target.
|
||||
/// </summary>
|
||||
/// <param name="advisorName">the advisor name</param>
|
||||
/// <param name="targetType">the target object's type</param>
|
||||
/// <param name="targetName">the target object's name</param>
|
||||
protected override bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
|
||||
{
|
||||
return (!usePrefix || advisorName.StartsWith(advisorObjectNamePrefix));
|
||||
}
|
||||
|
||||
private IList InstantiateCandidateAdvisors()
|
||||
{
|
||||
if (logger.IsDebugEnabled)
|
||||
{
|
||||
logger.Debug(string.Format("instantiating available advisors"));
|
||||
}
|
||||
|
||||
//This is ensured in AbstractAdvisorAutoProxyCreator. Will be more type safe once sync with Spring Java 2.x
|
||||
IConfigurableListableObjectFactory owningFactory = ObjectFactory as IConfigurableListableObjectFactory;
|
||||
if (owningFactory == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot use DefaultAdvisorAutoProxyCreator without a IListableObjectFactory");
|
||||
}
|
||||
|
||||
ArrayList candidateAdvisors = new ArrayList();
|
||||
|
||||
string[] advisorNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(
|
||||
owningFactory, typeof(IAdvisor), true, false);
|
||||
for (int i = 0; i < advisorNames.Length; i++)
|
||||
{
|
||||
string name = advisorNames[i];
|
||||
if ( (!usePrefix || name.StartsWith(advisorObjectNamePrefix)) && !owningFactory.IsCurrentlyInCreation(name))
|
||||
{
|
||||
try
|
||||
{
|
||||
IAdvisor advisor = (IAdvisor) owningFactory.GetObject(name);
|
||||
candidateAdvisors.Add(advisor);
|
||||
} catch (ObjectCreationException ex)
|
||||
{
|
||||
Exception rootEx = ex.GetBaseException();
|
||||
|
||||
|
||||
if (rootEx is ObjectCurrentlyInCreationException)
|
||||
{
|
||||
ObjectCurrentlyInCreationException oce = (ObjectCurrentlyInCreationException) rootEx;
|
||||
if (owningFactory.IsCurrentlyInCreation(oce.ObjectName))
|
||||
{
|
||||
if (logger.IsDebugEnabled)
|
||||
{
|
||||
logger.Debug(string.Format("Ignoring currently created advisor '{0}': exception message = {1}",
|
||||
name, ex.Message));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string[] aspectNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(
|
||||
owningFactory, typeof(IAdvisors), true, false);
|
||||
for (int i = 0; i < aspectNames.Length; i++)
|
||||
{
|
||||
string name = aspectNames[i];
|
||||
if (!usePrefix || name.StartsWith(advisorObjectNamePrefix))
|
||||
{
|
||||
IAdvisors advisors = (IAdvisors)owningFactory.GetObject(name);
|
||||
candidateAdvisors.AddRange(advisors.Advisors);
|
||||
}
|
||||
}
|
||||
|
||||
return candidateAdvisors;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Invoked by an <see cref="Spring.Objects.Factory.IObjectFactory"/>
|
||||
/// after it has injected all of an object's dependencies.
|
||||
/// </summary>
|
||||
public void AfterPropertiesSet()
|
||||
{
|
||||
advisors = InstantiateCandidateAdvisors();
|
||||
}
|
||||
|
||||
#region IObjectNameAware Members
|
||||
|
||||
/// <summary>
|
||||
/// Set the name of the object in the object factory that created this object.
|
||||
/// </summary>
|
||||
/// <value>The name of the object in the factory.</value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Invoked after population of normal object properties but before an init
|
||||
/// callback like <see cref="T:Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
/// <see cref="M:Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
/// method or a custom init-method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public string ObjectName
|
||||
{
|
||||
set
|
||||
{
|
||||
// If no infrastructure object name prefix has been set, override it.
|
||||
if (advisorObjectNamePrefix == null)
|
||||
{
|
||||
advisorObjectNamePrefix = value + SEPARATOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -71,11 +71,11 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// <summary>
|
||||
/// Identify as object to proxy if the object name is in the configured list of names.
|
||||
/// </summary>
|
||||
protected override bool IsEligibleForProxying( Type objType, string name )
|
||||
protected override bool IsEligibleForProxying( Type targetType, string targetName )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(this.ObjectNames, "ObjectNames");
|
||||
|
||||
bool shallProxy = PatternMatchUtils.IsObjectNameMatch(objType, name, this.ObjectNames, new PatternMatchUtils.ObjectNameMatchPredicate(IsMatch), ObjectFactoryUtils.FactoryObjectPrefix);
|
||||
bool shallProxy = PatternMatchUtils.IsObjectNameMatch(targetType, targetName, this.ObjectNames, new PatternMatchUtils.ObjectNameMatchPredicate(IsMatch), ObjectFactoryUtils.FactoryObjectPrefix);
|
||||
return shallProxy;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,11 +49,11 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// <summary>
|
||||
/// Determines, whether the given object shall be proxied.
|
||||
/// </summary>
|
||||
protected override bool IsEligibleForProxying( Type objType, string name )
|
||||
protected override bool IsEligibleForProxying( Type targetType, string targetName )
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(_pointcut, "Pointcut");
|
||||
|
||||
bool shallProxy = AopUtils.CanApply( _pointcut, objType, null );
|
||||
bool shallProxy = AopUtils.CanApply( _pointcut, targetType, null );
|
||||
return shallProxy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,15 +55,15 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
/// <remarks>
|
||||
/// Override this method to allow or reject proxying for the given object.
|
||||
/// </remarks>
|
||||
/// <param name="objType">the object's type</param>
|
||||
/// <param name="name">the name of the object</param>
|
||||
/// <param name="targetType">the object's type</param>
|
||||
/// <param name="targetName">the name of the object</param>
|
||||
/// <seealso cref="AbstractAutoProxyCreator.ShouldSkip"/>
|
||||
/// <returns>whether the given object shall be proxied.</returns>
|
||||
protected override bool IsEligibleForProxying(Type objType, string name)
|
||||
protected override bool IsEligibleForProxying(Type targetType, string targetName)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(_typeNameFilter, "TypeNames");
|
||||
|
||||
bool shallProxy = _typeNameFilter.Matches(objType);
|
||||
bool shallProxy = _typeNameFilter.Matches(targetType);
|
||||
return shallProxy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,9 @@
|
||||
<Compile Include="Aop\Framework\AopUtils.cs" />
|
||||
<Compile Include="Aop\Framework\AutoProxy\AbstractFilteringAutoProxyCreator.cs" />
|
||||
<Compile Include="Aop\Framework\AutoProxy\AttributeAutoProxyCreator.cs" />
|
||||
<Compile Include="Aop\Framework\AutoProxy\InfrastructureAdvisorAutoProxyCreator.cs" />
|
||||
<Compile Include="Aop\Framework\AutoProxy\InheritanceBasedAopConfigurer.cs" />
|
||||
<Compile Include="Aop\Framework\AutoProxy\ObjectFactoryAdvisorRetrievalHelper.cs" />
|
||||
<Compile Include="Aop\Framework\AutoProxy\PointcutFilteringAutoProxyCreator.cs" />
|
||||
<Compile Include="Aop\Framework\AutoProxy\TypeNameAutoProxyCreator.cs" />
|
||||
<Compile Include="Aop\Framework\DynamicMethodInvocation.cs" />
|
||||
|
||||
@@ -120,6 +120,11 @@ namespace Spring.Objects.Factory.Config
|
||||
/// </summary>
|
||||
string Scope { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the role hint for this object definition
|
||||
/// </summary>
|
||||
ObjectRole Role { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="System.Type"/> of the object definition (if any).
|
||||
/// </summary>
|
||||
|
||||
@@ -49,7 +49,6 @@ namespace Spring.Objects.Factory.Support
|
||||
private static readonly string SCOPE_SINGLETON = "singleton";
|
||||
private static readonly string SCOPE_PROTOTYPE = "prototype";
|
||||
|
||||
|
||||
#region Constructor (s) / Destructor
|
||||
|
||||
/// <summary>
|
||||
@@ -126,6 +125,7 @@ namespace Spring.Objects.Factory.Support
|
||||
IsAbstract = other.IsAbstract;
|
||||
// IsSingleton = other.IsSingleton;
|
||||
Scope = other.Scope;
|
||||
Role = other.Role;
|
||||
IsLazyInit = other.IsLazyInit;
|
||||
ConstructorArgumentValues
|
||||
= new ConstructorArgumentValues(other.ConstructorArgumentValues);
|
||||
@@ -271,6 +271,15 @@ namespace Spring.Objects.Factory.Support
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the role hint for this object definition
|
||||
/// </summary>
|
||||
public virtual ObjectRole Role
|
||||
{
|
||||
get { return role; }
|
||||
set { role = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this definition a <b>singleton</b>, with
|
||||
/// a single, shared instance returned on all calls to an enclosing
|
||||
@@ -797,6 +806,7 @@ namespace Spring.Objects.Factory.Support
|
||||
private bool isLazyInit = false;
|
||||
private bool isAbstract = false;
|
||||
private string scope = SCOPE_SINGLETON;
|
||||
private ObjectRole role = ObjectRole.ROLE_APPLICATION;
|
||||
private object objectType;
|
||||
private AutoWiringMode autowireMode = AutoWiringMode.No;
|
||||
private DependencyCheckingMode dependencyCheck = DependencyCheckingMode.None;
|
||||
|
||||
@@ -60,6 +60,11 @@ namespace Spring.Objects.Factory.Support
|
||||
/// </summary>
|
||||
new EventValues EventHandlerValues { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the role hint for this object definition
|
||||
/// </summary>
|
||||
new ObjectRole Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Return a description of the resource that this object definition
|
||||
/// came from (for the purpose of showing context in case of errors).
|
||||
|
||||
@@ -575,6 +575,7 @@
|
||||
<Compile Include="Objects\Factory\Config\ISingletonObjectRegistry.cs" />
|
||||
<Compile Include="Objects\Factory\Config\ObjectDefinitionHolder.cs" />
|
||||
<Compile Include="Objects\Factory\Config\ObjectDefinitionVisitor.cs" />
|
||||
<Compile Include="Objects\Factory\Config\ObjectRole.cs" />
|
||||
<Compile Include="Objects\Factory\Config\ResourceHandlerConfigurer.cs" />
|
||||
<Compile Include="Objects\Factory\Config\SharedStateAwareProcessor.cs" />
|
||||
<Compile Include="Objects\Factory\Config\SmartInstantiationAwareObjectPostProcessor.cs" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#region License
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
@@ -14,107 +14,106 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using Spring.Aop.Config;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Transaction.Interceptor;
|
||||
|
||||
namespace Spring.Transaction.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// IObjectDefinitionParser implementation that allows users to easily configure all the
|
||||
/// infrastructure objects required to enable attribute-driven transction demarcation.
|
||||
/// </summary>
|
||||
/// <author>Rob Harrop</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
public class AttributeDrivenObjectDefinitionParser : AbstractObjectDefinitionParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Object property name for injection the TransactionInterceptor
|
||||
/// </summary>
|
||||
private static readonly string TRANSACTION_INTERCEPTOR = "transactionInterceptor";
|
||||
|
||||
/// <summary>
|
||||
/// The '<code>proxy-target-type</code>' attribute
|
||||
/// </summary>
|
||||
private static readonly string PROXY_TARGET_TYPE = "proxy-target-type";
|
||||
|
||||
/// <summary>
|
||||
/// The '<code>order</code>' property/attribute
|
||||
/// </summary>
|
||||
private static readonly string ORDER = "order";
|
||||
|
||||
/// <summary>
|
||||
/// Central template method to actually parse the supplied XmlElement
|
||||
/// into one or more IObjectDefinitions.
|
||||
/// </summary>
|
||||
/// <param name="element">The element that is to be parsed into one or more <see cref="IObjectDefinition"/>s</param>
|
||||
/// <param name="parserContext">The the object encapsulating the current state of the parsing process;
|
||||
/// provides access to a <see cref="IObjectDefinitionRegistry"/></param>
|
||||
/// <returns>
|
||||
/// The primary IObjectDefinition resulting from the parsing of the supplied XmlElement
|
||||
/// </returns>
|
||||
protected override AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext)
|
||||
{
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Xml;
|
||||
using Spring.Aop.Config;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Transaction.Interceptor;
|
||||
|
||||
namespace Spring.Transaction.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// IObjectDefinitionParser implementation that allows users to easily configure all the
|
||||
/// infrastructure objects required to enable attribute-driven transction demarcation.
|
||||
/// </summary>
|
||||
/// <author>Rob Harrop</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
public class AttributeDrivenObjectDefinitionParser : AbstractObjectDefinitionParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Object property name for injection the TransactionInterceptor
|
||||
/// </summary>
|
||||
private static readonly string TRANSACTION_INTERCEPTOR = "transactionInterceptor";
|
||||
|
||||
/// <summary>
|
||||
/// The '<code>proxy-target-type</code>' attribute
|
||||
/// </summary>
|
||||
private static readonly string PROXY_TARGET_TYPE = "proxy-target-type";
|
||||
|
||||
/// <summary>
|
||||
/// The '<code>order</code>' property/attribute
|
||||
/// </summary>
|
||||
private static readonly string ORDER = "order";
|
||||
|
||||
/// <summary>
|
||||
/// Central template method to actually parse the supplied XmlElement
|
||||
/// into one or more IObjectDefinitions.
|
||||
/// </summary>
|
||||
/// <param name="element">The element that is to be parsed into one or more <see cref="IObjectDefinition"/>s</param>
|
||||
/// <param name="parserContext">The the object encapsulating the current state of the parsing process;
|
||||
/// provides access to a <see cref="IObjectDefinitionRegistry"/></param>
|
||||
/// <returns>
|
||||
/// The primary IObjectDefinition resulting from the parsing of the supplied XmlElement
|
||||
/// </returns>
|
||||
protected override AbstractObjectDefinition ParseInternal(XmlElement element, ParserContext parserContext)
|
||||
{
|
||||
ConfigureAutoProxyCreator(parserContext, element);
|
||||
|
||||
string transactionManagerName = GetAttributeValue(element, TxNamespaceUtils.TRANSACTION_MANAGER_ATTRIBUTE);
|
||||
Type sourceType = typeof (AttributesTransactionAttributeSource);
|
||||
|
||||
//Create the TransactionInterceptor definition.
|
||||
RootObjectDefinition interceptorDefinition = new RootObjectDefinition(typeof (TransactionInterceptor));
|
||||
interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_MANAGER_PROPERTY,
|
||||
new RuntimeObjectReference(transactionManagerName));
|
||||
interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE,
|
||||
new RootObjectDefinition(sourceType));
|
||||
|
||||
//Create the TransactionAttributeSourceAdvisor definition.
|
||||
RootObjectDefinition advisorDefinition = new RootObjectDefinition(typeof (TransactionAttributeSourceAdvisor));
|
||||
advisorDefinition.PropertyValues.Add(TRANSACTION_INTERCEPTOR, interceptorDefinition);
|
||||
if (element.HasAttribute(ORDER))
|
||||
{
|
||||
advisorDefinition.PropertyValues.Add(ORDER, GetAttributeValue(element, ORDER));
|
||||
}
|
||||
|
||||
return advisorDefinition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the auto proxy creator.
|
||||
/// </summary>
|
||||
/// <param name="parserContext">The parser context.</param>
|
||||
/// <param name="element">The element.</param>
|
||||
private static void ConfigureAutoProxyCreator(ParserContext parserContext, XmlElement element)
|
||||
{
|
||||
AopNamespaceUtils.RegisterAutoProxyCreatorIfNecessary(parserContext, element);
|
||||
|
||||
bool proxyTargetClass =
|
||||
parserContext.ParserHelper.IsTrueStringValue(GetAttributeValue(element, PROXY_TARGET_TYPE));
|
||||
if (proxyTargetClass)
|
||||
{
|
||||
AopNamespaceUtils.ForceAutoProxyCreatorToUseDecoratorProxy(parserContext.Registry);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether an ID should be generated instead of read
|
||||
/// from the passed in XmlElement.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if should generate id; otherwise, <c>false</c>.</value>
|
||||
/// <remarks>Note that this flag is about always generating an ID; the parser
|
||||
/// won't even check for an "id" attribute in this case.
|
||||
/// </remarks>
|
||||
protected override bool ShouldGenerateId
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
string transactionManagerName = GetAttributeValue(element, TxNamespaceUtils.TRANSACTION_MANAGER_ATTRIBUTE);
|
||||
Type sourceType = typeof(AttributesTransactionAttributeSource);
|
||||
|
||||
//Create the TransactionInterceptor definition.
|
||||
RootObjectDefinition interceptorDefinition = new RootObjectDefinition(typeof(TransactionInterceptor));
|
||||
interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_MANAGER_PROPERTY,
|
||||
new RuntimeObjectReference(transactionManagerName));
|
||||
interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE,
|
||||
new RootObjectDefinition(sourceType));
|
||||
|
||||
//Create the TransactionAttributeSourceAdvisor definition.
|
||||
RootObjectDefinition advisorDefinition = new RootObjectDefinition(typeof(TransactionAttributeSourceAdvisor));
|
||||
advisorDefinition.PropertyValues.Add(TRANSACTION_INTERCEPTOR, interceptorDefinition);
|
||||
if (element.HasAttribute(ORDER))
|
||||
{
|
||||
advisorDefinition.PropertyValues.Add(ORDER, GetAttributeValue(element, ORDER));
|
||||
}
|
||||
|
||||
return advisorDefinition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the auto proxy creator.
|
||||
/// </summary>
|
||||
/// <param name="parserContext">The parser context.</param>
|
||||
/// <param name="element">The element.</param>
|
||||
private static void ConfigureAutoProxyCreator(ParserContext parserContext, XmlElement element)
|
||||
{
|
||||
AopNamespaceUtils.RegisterAutoProxyCreatorIfNecessary(parserContext, element);
|
||||
|
||||
bool proxyTargetClass = parserContext.ParserHelper.IsTrueStringValue(GetAttributeValue(element, PROXY_TARGET_TYPE));
|
||||
if (proxyTargetClass)
|
||||
{
|
||||
AopNamespaceUtils.ForceAutoProxyCreatorToUseDecoratorProxy(parserContext.Registry);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether an ID should be generated instead of read
|
||||
/// from the passed in XmlElement.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if should generate id; otherwise, <c>false</c>.</value>
|
||||
/// <remarks>Note that this flag is about always generating an ID; the parser
|
||||
/// won't even check for an "id" attribute in this case.
|
||||
/// </remarks>
|
||||
protected override bool ShouldGenerateId
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,9 +121,9 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
this.ObjectFactory = objectFactory;
|
||||
}
|
||||
|
||||
protected override object[] GetAdvicesAndAdvisorsForObject(Type objType, string name, ITargetSource customTargetSource)
|
||||
protected override object[] GetAdvicesAndAdvisorsForObject(Type targetType, string targetName, ITargetSource customTargetSource)
|
||||
{
|
||||
if (typeof(IFactoryObject).IsAssignableFrom(objType))
|
||||
if (typeof(IFactoryObject).IsAssignableFrom(targetType))
|
||||
{
|
||||
return DO_NOT_PROXY;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Spring.Aop.Framework.AutoProxy
|
||||
Assert.IsTrue(AopUtils.IsAopProxy(context.GetObject("independentObject")));
|
||||
|
||||
// products of the factory created at runtime should be proxied
|
||||
Assert.IsTrue(AopUtils.IsAopProxy(context.GetObject("testObjectFactory")));
|
||||
Assert.IsFalse(AopUtils.IsAopProxy(context.GetObject("testObjectFactory")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ limitations under the License.
|
||||
|
||||
</factoryAdapter>
|
||||
-->
|
||||
<factoryAdapter type="Common.Logging.Simple.NoOpLoggerFactoryAdapter, Common.Logging">
|
||||
<factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging">
|
||||
<arg key="level" value="ALL" />
|
||||
</factoryAdapter>
|
||||
|
||||
</logging>
|
||||
|
||||
@@ -83,6 +83,11 @@ namespace Spring.Objects.Factory
|
||||
set { throw new System.NotImplementedException(); }
|
||||
}
|
||||
|
||||
public ObjectRole Role
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public Type ObjectType
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{ACD39D47-1811-40FA-9E7E-5DEA5B9CE6C0}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@@ -166,6 +166,7 @@
|
||||
<EmbeddedResource Include="Data\AutoDeclarativeTxTests.xml" />
|
||||
<EmbeddedResource Include="Data\Common\AdditionalProviders.xml" />
|
||||
<Content Include="Spring.Data.Tests.dll.config" />
|
||||
<Content Include="Transaction\Config\TxNamespaceParserTests_TxAttributeDriven.xml" />
|
||||
<EmbeddedResource Include="Transaction\Interceptor\MatchAlwaysTransactionAttributeSourceTests.xml" />
|
||||
<EmbeddedResource Include="Transaction\Config\TxNamespaceParserTests.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user