如何在Spring.NET中使用DefaultAdvisorAutoProxyCreator定义原型拦截器

时间:2012-02-12 18:58:41

标签: aop spring.net

我是Spring.NET的新手,我只是在尝试不同的东西。作为测试的一部分,我创建了一个简单的对象:

public interface ICommand {
    void Execute(object context);
}

有一个实现:

public class ServiceCommand : ICommand {
    public ServiceCommand() {
        Console.WriteLine("########## {0} ##########", GetType().Name);
    }

    public void Execute(object context) {
        Console.WriteLine("Service implementation: {0}.{1}", GetType().Name, MethodBase.GetCurrentMethod().Name);
    }
}

最后,我的建议如下:

public class ConsoleLoggingBeforeAdvice : IMethodBeforeAdvice {
    public ConsoleLoggingBeforeAdvice() {
        Console.WriteLine("########## {0} ##########", GetType().Name);
    }

    public void Before(MethodInfo method, object[] args, object target) {
        Console.WriteLine("Intercepted call to this method: {0}", method.Name);
        Console.WriteLine("     The target is             : {0}", target);
        Console.WriteLine("     The arguments are         : ");
        if (args != null) {
            foreach (object arg in args) {
                Console.WriteLine("\t: {0}", arg);
            }
        }
    }
}

正如您所看到的,这些内容大部分来自Spring.NET快速入门示例。

因此,我将ServiceCommand配置为通过ProxyFactoryObject包装在ConsoleLoggingBeforeAdvice中,并将这两个对象标记为原型(请参阅下面的配置)。这按预期工作:每次我们请求ServiceCommand时,都会创建对象和关联拦截器的新实例:

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net">
    <object id="ConsoleLoggingBeforeAdvice" type="Spring.Aop.Support.DefaultPointcutAdvisor" singleton="false">
        <property name="Advice">
            <object type="Spring.Examples.AopQuickStart.ConsoleLoggingBeforeAdvice"/>
        </property>
    </object>

    <object id="ServiceCommandTarget" type="Spring.Examples.AopQuickStart.ServiceCommand" singleton="false"/>

    <object id="ServiceCommand" type ="Spring.Aop.Framework.ProxyFactoryObject">
        <property name="IsSingleton" value="false"/>
        <property name="TargetName" value="ServiceCommandTarget"/>
        <property name="InterceptorNames">
            <list>
                <value>ConsoleLoggingBeforeAdvice</value>
            </list>
        </property>
    </object>
</objects>

然而,当我尝试通过DefaultAdvisorAutoProxyCreator获得相同的结果时,一切都有效,除了拦截器总是被创建为Singleton(即使它被配置为singleton =“false”)。配置如下:

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net">
    <object id="ConsoleLoggingBeforeAdvice" type="Spring.Aop.Support.DefaultPointcutAdvisor" singleton="false">
        <property name="Advice">
            <object type="Spring.Examples.AopQuickStart.ConsoleLoggingBeforeAdvice"/>
        </property>
    </object>

    <object id="ServiceCommand" type="Spring.Examples.AopQuickStart.ServiceCommand" singleton="false"/>
    <object type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator"/>
</objects>

现在,我如何确保DefaultAdvisorAutoProxyCreator将对象和关联的拦截器都视为原型?

1 个答案:

答案 0 :(得分:1)

好的,我已经发现在DefaultAdvisorAutoProxyCreator上设置InterceptorNames会正确地将拦截器实例化为原型(如果它们是这样配置的话)。但是由于DefaultAdvisorAutoProxyCreator应该能够从顾问程序中选择拦截器并遵守其配置设置,因此这种方式感觉不正确。

我仍然不清楚如何在不同的场景下创建原型拦截器。例如,我在使用DefaultAdvisorAutoProxyCreator时创建线程范围拦截器的所有尝试都失败了。

无论如何,这是适用于我的xml配置:

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net" default-autowire="constructor">
    <object id="ConsoleLoggingBeforeAdvice" type="Spring.Aop.Support.DefaultPointcutAdvisor" singleton="false">
        <property name="Advice">
            <object type="Spring.Examples.AopQuickStart.ConsoleLoggingBeforeAdvice"/>
        </property>
    </object>

    <object id="ServiceCommand" type="Spring.Examples.AopQuickStart.ServiceCommand" singleton="false"/>

    <object type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator">
        <property name="InterceptorNames" value="ConsoleLoggingBeforeAdvice"/>
    </object>
</objects>

我对创建原型拦截器的想法感到困惑。是拦截器应该被推荐还是被推荐为原型,还是应该总是单身?