SPRNET-1235

This commit is contained in:
eeichinger
2009-07-26 20:36:59 +00:00
parent 6091e9c491
commit 477b829469
14 changed files with 294 additions and 41 deletions

View File

@@ -55,7 +55,7 @@ namespace Spring.Aop.Config
/// <param name="sourceElement">The source element.</param>
public static void RegisterAutoProxyCreatorIfNecessary(ParserContext parserContext, XmlElement sourceElement)
{
RegisterApcAsRequired(typeof(DefaultAdvisorAutoProxyCreator), parserContext);
RegisterApcAsRequired(typeof(InfrastructureAdvisorAutoProxyCreator), parserContext);
}
/// <summary>

View File

@@ -128,6 +128,7 @@ namespace Spring.Aop.Config
{
ObjectDefinitionBuilder advisorDefinitionBuilder =
parserContext.ParserHelper.CreateRootObjectDefinitionBuilder(typeof(DefaultObjectFactoryPointcutAdvisor));
advisorDefinitionBuilder.RawObjectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
if (advisorElement.HasAttribute(ORDER_PROPERTY))
{

View File

@@ -57,7 +57,7 @@ namespace Spring.Aop.Framework.AutoProxy
public abstract class AbstractAdvisorAutoProxyCreator : AbstractAutoProxyCreator
{
private readonly ILog Log;
private ObjectFactoryAdvisorRetrievalHelper _advisorRetrievalHelper;
private IAdvisorRetrievalHelper _advisorRetrievalHelper;
/// <summary>
/// Initialize
@@ -76,12 +76,12 @@ namespace Spring.Aop.Framework.AutoProxy
{
set
{
base.ObjectFactory = value;
if (!(value is IConfigurableListableObjectFactory))
{
throw new InvalidOperationException("Can not use AdvisorAutoProxyCreator without a ConfigurableListableObjectFactory");
}
InitObjectFactory((IConfigurableListableObjectFactory) value);
base.ObjectFactory = value;
InitObjectFactory((IConfigurableListableObjectFactory)value);
}
}
@@ -92,7 +92,21 @@ namespace Spring.Aop.Framework.AutoProxy
/// <param name="objectFactory"></param>
protected virtual void InitObjectFactory(IConfigurableListableObjectFactory objectFactory)
{
_advisorRetrievalHelper = new ObjectFactoryAdvisorRetrievalHelperAdapter(this, objectFactory);
_advisorRetrievalHelper = CreateAdvisorRetrievalHelper(objectFactory);
}
/// <summary>
/// Create the <see cref="IAdvisorRetrievalHelper"/> for retrieving the list of
/// applicable advisor objects. The default implementation calls back into
/// <see cref="IsEligibleAdvisorObject"/> thus it usually is sufficient to just
/// override <see cref="IsEligibleAdvisorObject"/>. Override <see cref="CreateAdvisorRetrievalHelper"/>
/// only if you know what you are doing!
/// </summary>
/// <param name="objectFactory"></param>
/// <returns></returns>
protected virtual IAdvisorRetrievalHelper CreateAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory)
{
return new ObjectFactoryAdvisorRetrievalHelperAdapter(this, objectFactory);
}
/// <summary>
@@ -264,7 +278,8 @@ namespace Spring.Aop.Framework.AutoProxy
protected override bool IsEligibleObject(string advisorName, Type objectType, string objectName)
{
return _owner.IsEligibleAdvisorObject(advisorName, objectType, objectName);
return base.IsEligibleObject(advisorName, objectType, objectName)
&& _owner.IsEligibleAdvisorObject(advisorName, objectType, objectName);
}
}
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <20> 2002-2005 the original author or authors.
* Copyright <20> 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,6 @@
#endregion
#region Imports
using System;
using System.Collections;
using System.Reflection;
@@ -35,8 +33,6 @@ using Spring.Objects.Factory;
using Spring.Objects.Factory.Config;
using Spring.Util;
#endregion
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
@@ -78,7 +74,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// <summary>
/// The logger for this class hierarchy.
/// </summary>
protected readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected readonly ILog logger;
/// <summary>
/// Convenience constant for subclasses: Return value for "do not proxy".
@@ -105,10 +101,13 @@ namespace Spring.Aop.Framework.AutoProxy
/// </summary>
private IAdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.Instance;
/// <summary>
///
/// Indicates whether to mark the create proxy as immutable.
/// </summary>
/// <remarks>
/// Setting this to true effectively disables modifying the generated
/// proxy's advisor configuration
/// </remarks>
private bool freezeProxy = false;
/// <summary>
@@ -218,6 +217,18 @@ namespace Spring.Aop.Framework.AutoProxy
#endregion
#region Constructor
/// <summary>
/// Create a new instance of this AutoProxyCreator
/// </summary>
protected AbstractAutoProxyCreator()
{
logger = LogManager.GetLogger(this.GetType());
}
#endregion
#region IObjectPostProcessor Members
/// <summary>

View File

@@ -124,7 +124,8 @@ namespace Spring.Aop.Framework.AutoProxy
/// <param name="targetName">the target object's name</param>
protected override bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
{
return (!usePrefix || advisorName.StartsWith(advisorObjectNamePrefix));
return (!usePrefix || advisorName.StartsWith(advisorObjectNamePrefix))
&& base.IsEligibleAdvisorObject(advisorName, targetType, targetName);
}
/// <summary>

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections;
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// Interface encapsulating the advisor retrieval strategy used by
/// an <see cref="AbstractAdvisorAutoProxyCreator"/> to retrieve the
/// applicable list of advisor objects.
/// </summary>
public interface IAdvisorRetrievalHelper
{
/// <summary>
/// Get the list of advisor objects to apply on the target.
/// </summary>
IList FindAdvisorObjects(Type targetType, string targetName);
}
}

View File

@@ -24,22 +24,38 @@ using Spring.Objects.Factory.Config;
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// A special version of an APC that explicitely cares for infrastructure (=internal)
/// advisors only
/// </summary>
/// <author>Erich Eichinger</author>
internal class InfrastructureAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator
public class InfrastructureAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator
{
private IConfigurableListableObjectFactory _objectFactory;
protected override void InitObjectFactory(IConfigurableListableObjectFactory objectFactory)
/// <summary>
/// Overridden to create a special version of an <see cref="IAdvisorRetrievalHelper"/>
/// that accepts only infrastructure advisor definitions
/// </summary>
/// <param name="objectFactory"></param>
/// <returns></returns>
protected override IAdvisorRetrievalHelper CreateAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory)
{
base.InitObjectFactory(objectFactory);
_objectFactory = objectFactory;
return new InfrastructurAdvisorRetrievalHelper(this, objectFactory);
}
protected override bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
private class InfrastructurAdvisorRetrievalHelper : ObjectFactoryAdvisorRetrievalHelper
{
return _objectFactory.ContainsObjectDefinition(advisorName)
&& _objectFactory.GetObjectDefinition(advisorName).Role == ObjectRole.ROLE_INFRASTRUCTURE;
private readonly InfrastructureAdvisorAutoProxyCreator _owner;
public InfrastructurAdvisorRetrievalHelper(InfrastructureAdvisorAutoProxyCreator owner, IConfigurableListableObjectFactory objectFactory)
: base(objectFactory)
{
_owner = owner;
}
protected override bool IsEligibleObject(string advisorName, Type objectType, string objectName)
{
return this.ObjectFactory.ContainsObjectDefinition(advisorName)
&& this.ObjectFactory.GetObjectDefinition(advisorName).Role == ObjectRole.ROLE_INFRASTRUCTURE;
}
}
}
}

View File

@@ -32,20 +32,28 @@ namespace Spring.Aop.Framework.AutoProxy
/// use with auto-proxying.
/// </summary>
/// <author>Erich Eichinger</author>
public class ObjectFactoryAdvisorRetrievalHelper
public class ObjectFactoryAdvisorRetrievalHelper : IAdvisorRetrievalHelper
{
private readonly ILog _log;
private readonly IConfigurableListableObjectFactory _owningFactory;
private readonly IConfigurableListableObjectFactory _objectFactory;
private string[] _cachedObjectNames;
/// <summary>
/// Create a new helper for the specified <paramref name="owningFactory"/>.
/// The object factory to lookup advisors from
/// </summary>
public ObjectFactoryAdvisorRetrievalHelper(IConfigurableListableObjectFactory owningFactory )
public IConfigurableListableObjectFactory ObjectFactory
{
AssertUtils.ArgumentNotNull(owningFactory, "owningFactory");
get { return _objectFactory; }
}
/// <summary>
/// Create a new helper for the specified <paramref name="objectFactory"/>.
/// </summary>
public ObjectFactoryAdvisorRetrievalHelper(IConfigurableListableObjectFactory objectFactory )
{
AssertUtils.ArgumentNotNull(objectFactory, "objectFactory");
_log = LogManager.GetLogger(this.GetType());
_owningFactory = owningFactory;
_objectFactory = objectFactory;
}
/// <summary>
@@ -68,7 +76,7 @@ namespace Spring.Aop.Framework.AutoProxy
for (int i = 0; i < advisorNames.Length; i++)
{
string name = advisorNames[i];
if (IsEligibleObject(name, targetType, targetName) && !_owningFactory.IsCurrentlyInCreation(name))
if (IsEligibleObject(name, targetType, targetName) && !_objectFactory.IsCurrentlyInCreation(name))
{
try
{
@@ -80,7 +88,7 @@ namespace Spring.Aop.Framework.AutoProxy
if (rootEx is ObjectCurrentlyInCreationException)
{
ObjectCurrentlyInCreationException oce = (ObjectCurrentlyInCreationException)rootEx;
if (_owningFactory.IsCurrentlyInCreation(oce.ObjectName))
if (_objectFactory.IsCurrentlyInCreation(oce.ObjectName))
{
if (_log.IsDebugEnabled)
{
@@ -105,7 +113,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// <param name="advisorName">the object name of the advisor to add</param>
private void AddAdvisorCandidate(ArrayList advisors, string advisorName)
{
object advisorCandidate = _owningFactory.GetObject(advisorName);
object advisorCandidate = _objectFactory.GetObject(advisorName);
if (advisorCandidate is IAdvisor)
{
advisors.Add(advisorCandidate);
@@ -136,9 +144,9 @@ namespace Spring.Aop.Framework.AutoProxy
if (_cachedObjectNames == null)
{
ArrayList candidateNameList = new ArrayList();
string[] advisorCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors( _owningFactory, typeof(IAdvisor), true, false);
string[] advisorCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors( _objectFactory, typeof(IAdvisor), true, false);
candidateNameList.AddRange(advisorCandidateNames);
string[] advisorsCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_owningFactory, typeof(IAdvisors), true, false);
string[] advisorsCandidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_objectFactory, typeof(IAdvisors), true, false);
candidateNameList.AddRange(advisorsCandidateNames);
_cachedObjectNames = (string[]) candidateNameList.ToArray(typeof(string));
}
@@ -149,14 +157,16 @@ namespace Spring.Aop.Framework.AutoProxy
/// <summary>
/// Determine, whether the specified aspect object is eligible.
/// The default implementation always returns <c>true</c>.
/// The default implementation accepts all except for advisors that are
/// part of the internal infrastructure.
/// </summary>
/// <param name="advisorName">the name of the candidate advisor</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 bool IsEligibleObject(string advisorName, Type objectType, string objectName )
{
return true;
}
return this.ObjectFactory.ContainsObjectDefinition(advisorName)
&& this.ObjectFactory.GetObjectDefinition(advisorName).Role != ObjectRole.ROLE_INFRASTRUCTURE;
}
}
}

View File

@@ -138,6 +138,7 @@
<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\IAdvisorRetrievalHelper.cs" />
<Compile Include="Aop\Framework\AutoProxy\InfrastructureAdvisorAutoProxyCreator.cs" />
<Compile Include="Aop\Framework\AutoProxy\InheritanceBasedAopConfigurer.cs" />
<Compile Include="Aop\Framework\AutoProxy\ObjectFactoryAdvisorRetrievalHelper.cs" />

View File

@@ -71,6 +71,7 @@ namespace Spring.Transaction.Config
//Create the TransactionInterceptor definition.
RootObjectDefinition interceptorDefinition = new RootObjectDefinition(typeof(TransactionInterceptor));
interceptorDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_MANAGER_PROPERTY,
new RuntimeObjectReference(transactionManagerName));
interceptorDefinition.PropertyValues.Add(TxNamespaceUtils.TRANSACTION_ATTRIBUTE_SOURCE,
@@ -78,6 +79,7 @@ namespace Spring.Transaction.Config
//Create the TransactionAttributeSourceAdvisor definition.
RootObjectDefinition advisorDefinition = new RootObjectDefinition(typeof(TransactionAttributeSourceAdvisor));
advisorDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
advisorDefinition.PropertyValues.Add(TRANSACTION_INTERCEPTOR, interceptorDefinition);
if (element.HasAttribute(ORDER))
{

View File

@@ -0,0 +1,91 @@
#region License
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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 AopAlliance.Aop;
using NUnit.Framework;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// </summary>
/// <author>Erich Eichinger</author>
[TestFixture]
public class AbstractAdvisorAutoProxyCreatorTests
{
public class TestAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator
{
public object[] GetAdvicesAndAdvisorsForObject(Type targetType, string targetName)
{
return base.GetAdvicesAndAdvisorsForObject(targetType, targetName, null);
}
protected override bool IsEligibleAdvisorObject(string advisorName, Type targetType, string targetName)
{
return true;
}
}
public class TestAdvisor : IAdvisor
{
public string Name;
#region Implementation of IAdvisor
public bool IsPerInstance
{
get { throw new NotImplementedException(); }
}
public IAdvice Advice
{
get { throw new NotImplementedException(); }
}
#endregion
}
[Test]
public void DoesNotAcceptInfrastructureAdvisorsDuringScanning()
{
DefaultListableObjectFactory of = new DefaultListableObjectFactory();
GenericObjectDefinition infrastructureAdvisorDefinition = new GenericObjectDefinition();
infrastructureAdvisorDefinition.ObjectType = typeof (TestAdvisor);
infrastructureAdvisorDefinition.PropertyValues.Add("Name", "InfrastructureAdvisor");
infrastructureAdvisorDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
of.RegisterObjectDefinition("infrastructure", infrastructureAdvisorDefinition);
GenericObjectDefinition regularAdvisorDefinition = new GenericObjectDefinition();
regularAdvisorDefinition.ObjectType = typeof (TestAdvisor);
regularAdvisorDefinition.PropertyValues.Add("Name", "RegularAdvisor");
// regularAdvisorDefinition.Role = ObjectRole.ROLE_APPLICATION;
of.RegisterObjectDefinition("regular", regularAdvisorDefinition);
TestAdvisorAutoProxyCreator apc = new TestAdvisorAutoProxyCreator();
apc.ObjectFactory = of;
object[] advisors = apc.GetAdvicesAndAdvisorsForObject(typeof (object), "dummyTarget");
Assert.AreEqual(1, advisors.Length);
Assert.AreEqual( "RegularAdvisor", ((TestAdvisor)advisors[0]).Name );
}
}
}

View File

@@ -22,7 +22,6 @@ using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using AopAlliance.Aop;
using NUnit.Framework;
using Spring.Aop.Interceptor;
using Spring.Objects.Factory;

View File

@@ -0,0 +1,86 @@
#region License
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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 AopAlliance.Aop;
using NUnit.Framework;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
namespace Spring.Aop.Framework.AutoProxy
{
/// <summary>
/// </summary>
/// <author>Erich Eichinger</author>
[TestFixture]
public class InfrastructureAdvisorAutoProxyCreatorTests
{
public class TestAdvisorAutoProxyCreator : InfrastructureAdvisorAutoProxyCreator
{
public object[] GetAdvicesAndAdvisorsForObject(Type targetType, string targetName)
{
return base.GetAdvicesAndAdvisorsForObject(targetType, targetName, null);
}
}
public class TestAdvisor : IAdvisor
{
public string Name;
#region Implementation of IAdvisor
public bool IsPerInstance
{
get { throw new NotImplementedException(); }
}
public IAdvice Advice
{
get { throw new NotImplementedException(); }
}
#endregion
}
[Test]
public void DoesAcceptInfrastructureAdvisorsOnlyDuringScanning()
{
DefaultListableObjectFactory of = new DefaultListableObjectFactory();
GenericObjectDefinition infrastructureAdvisorDefinition = new GenericObjectDefinition();
infrastructureAdvisorDefinition.ObjectType = typeof(TestAdvisor);
infrastructureAdvisorDefinition.PropertyValues.Add("Name", "InfrastructureAdvisor");
infrastructureAdvisorDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
of.RegisterObjectDefinition("infrastructure", infrastructureAdvisorDefinition);
GenericObjectDefinition regularAdvisorDefinition = new GenericObjectDefinition();
regularAdvisorDefinition.ObjectType = typeof(TestAdvisor);
regularAdvisorDefinition.PropertyValues.Add("Name", "RegularAdvisor");
// regularAdvisorDefinition.Role = ObjectRole.ROLE_APPLICATION;
of.RegisterObjectDefinition("regular", regularAdvisorDefinition);
TestAdvisorAutoProxyCreator apc = new TestAdvisorAutoProxyCreator();
apc.ObjectFactory = of;
object[] advisors = apc.GetAdvicesAndAdvisorsForObject(typeof(object), "dummyTarget");
Assert.AreEqual(1, advisors.Length);
Assert.AreEqual("InfrastructureAdvisor", ((TestAdvisor)advisors[0]).Name);
}
}
}

View File

@@ -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>{2111596A-0327-4C9D-8919-294FBD988A23}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -125,10 +125,12 @@
<Compile Include="Aop\Framework\AopContextTests.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Aop\Framework\AutoProxy\AbstractAdvisorAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\AbstractAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\AdvisorAutoProxyCreatorCircularReferencesTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\AdvisorAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\AttributeAutoProxyCreatorTests.cs" />
<Compile Include="Aop\Framework\AutoProxy\InfrastructureAdvisorAutoProxyCreator.cs" />
<Compile Include="Aop\Framework\AutoProxy\LogicalThreadContextAdvice.cs" />
<Compile Include="Aop\Framework\AutoProxy\NoSetterProperties.cs" />
<Compile Include="Aop\Framework\AutoProxy\ObjectNameAutoProxyCreatorTests.cs" />