【问题标题】:Does Spring.NET Support Creating Custom Object Lifetimes?Spring.NET 是否支持创建自定义对象生命周期?
【发布时间】:2012-02-12 19:24:08
【问题描述】:

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

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

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

【问题讨论】:

    标签: aop spring.net object-lifetime


    【解决方案1】:

    好的,所以我实际上问了另一个问题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 接口的自定义类型。

    这是一个简单的 ITargetSourceCreator 实现,它创建了一个 ThreadLocalTargetSourceCreator:

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

    【讨论】:

      猜你喜欢
      • 2021-06-21
      • 2013-10-02
      • 2016-07-31
      • 2014-12-22
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      • 2021-06-14
      • 2021-05-23
      相关资源
      最近更新 更多