2

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

即使我是该框架的新手,我认为情况可能并非如此。根据我目前的研究,我认为可以通过实现 ITargetSource 接口来定义自定义生命周期,但可以说,这个接口可以做的远不止这些(比如一些预定义的实现包括对象池和热交换目标等)。

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

4

1 回答 1

3

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

因此,总而言之,可以通过实现 ITargetSource 接口来创建 Spring.NET 中的自定义生命周期,但可以说,它是一个微妙的接口,可以用来围绕创建目标做一些花哨的事情。已经有很少的实现可用,包括(但不限于):

  • 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 接口并对其进行适当配置来创建自定义生命周期。

于 2012-02-19T06:00:29.570 回答