Spring.NET是否支持创建自定义对象生命周期?

时间:2012-02-12 19:24:09

标签: aop spring.net object-lifetime

在书Dependency Injection in .NET中,作者说Spring.NET不支持创建自定义对象生存期(参见第12.2节[管理生命周期]的最后一段)。

即使我是框架的新手,我认为情况可能并非如此。根据我到目前为止的研究,我认为可以通过实现ITargetSource接口来定义自定义生命周期,但可以说,这个界面可以做更多的事情(就像一些预定义的实现包括对象池和热插拔目标等)。

我的理解是否正确?如果是,创建和配置自定义生命周期的确切逻辑步骤是什么?如果不是,如何在Spring.NET中创建自定义对象生存期?

1 个答案:

答案 0 :(得分:3)

好的,所以我实际上问了另一个问题here,似乎在这个过程中回答了这个问题(这是一个极少数情况下你用自己发布的一个答案回答你自己的两个问题)。如果您关注其他问题,您会发现在Spring.NET中定义自定义生命周期确实是可能的。

总而言之,Spring.NET中的自定义生命周期可以通过实现ITargetSource接口来创建,但可以说,它是一个微妙的界面,可用于创建目标的奇特事物。已有的实现很少,包括(但不限于):

  • SingletonTargetSource(提供单例生存期)
  • PrototypeTargetSource(提供瞬态生命周期)
  • ThreadLocalTargetSource(提供线程范围的生存期)
  • SimplePoolTargetSource(提供对象池)
  • HotSwappableTargetSource(提供在运行时交换目标的功能)

有趣的是,根据您想要的生命周期,对您的对象应用生命周期可能会有很大差异。 Spring.NET中的所有对象默认都是单例。要将对象指定为原型(Spring.NET代表瞬态),请按如下方式设置singleton =“false”:

<object id="..." type="..." singleton="false"/>

不幸的是,其余提供的生命周期(包括您的自定义实现)没有这样方便的属性。所以,假设您要配置具有线程局部范围的对象。以下是使用ProxyFactoryObject执行此操作的方法:

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

    <object id="ServiceCommandTargetSource" type="Spring.Aop.Target.ThreadLocalTargetSource">
        <property name="TargetObjectName" value="ServiceCommandTarget"/>
    </object>

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

    <object name="ServiceCommand" type="Spring.Aop.Framework.ProxyFactoryObject">
        <property name="TargetSource" ref="ServiceCommandTargetSource"/>
        <property name="InterceptorNames">
            <list>
                <value>ConsoleLoggingBeforeAdvisor</value>
            </list>
        </property>
    </object>
</objects>

同样,如果您希望获得与上述配置完全相同的结果但使用DefaultAdvisorAutoProxyCreator,则必须以完全不同的方式执行此操作,包括实现实现ITargetSourceCreator接口的自定义类型。

这是一个创建ThreadLocalTargetSourceCreator的裸骨ITargetSourceCreator实现:

namespace Spring.Examples.AopQuickStart {
    public class ThreadLocalTargetSourceCreator : AbstractPrototypeTargetSourceCreator, ITargetSourceCreator {
        private readonly ThreadLocalTargetSource _threadLocalTargetSource;

        public ThreadLocalTargetSourceCreator() {
            _threadLocalTargetSource = new ThreadLocalTargetSource();
        }

        protected override AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name, IObjectFactory factory) {
            return _threadLocalTargetSource;
        }
    }
}

最后,您需要使用以下配置将上述ITargetSourceCreator与DefaultAdvisorAutoProxyCreator配合使用,以在线程局部范围内创建目标类型的实例:

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net" default-autowire="constructor">
    <object id="ConsoleLoggingBeforeAdvice" type="Spring.Aop.Support.DefaultPointcutAdvisor">
        <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="CustomTargetSourceCreators">
            <list element-type="Spring.Aop.Framework.AutoProxy.ITargetSourceCreator">
                <object type="Spring.Examples.AopQuickStart.ThreadLocalTargetSourceCreator"/>
            </list>
        </property>
    </object>
</objects>

在我看来,配置除单例(默认)和原型之外的生命周期的方式有些不直观,并且在不同类型的代理工厂实现(ProxyFactoryObject与DefaultAdvisorAutoProxyCreator)之间绝对不简化

总之,是的,Spring.NET确实支持自定义生命周期。如果预定义的生命周期都不符合您的要求,您可以通过实施ITargetSource接口并对其进行适当配置来创建自定义生命周期。