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

发布于 2025-01-05 04:34:50 字数 378 浏览 3 评论 0原文

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

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

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

In the book Dependency Injection in .NET, the author says that Spring.NET doesn't support creation of custom object lifetimes (See last paragraph of section 12.2 [Managing lifetime]).

Even though I am new to the framework, I think this may not be the case. Based on my research so far, I think one can define custom lifetimes by implementing the ITargetSource interface, though, arguably, this interface can do much more than that (like some predefined implementations include object pooling and hot-swappable targets etc.).

Is my understanding correct? If yes, what are the exact logical steps for creating AND configuring a custom lifetime? If no, how does one create a custom object lifetime in Spring.NET?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

茶色山野 2025-01-12 04:34:50

好的,所以我实际上问了另一个问题这里 并且似乎在此过程中回答了这个问题(这是极少数情况之一,您用自己发布的一个答案回答了两个自己的问题)。如果您遵循另一个问题,您将发现确实可以在 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 接口并进行适当配置来创建自定义生命周期。

Ok, so I actually asked another question here and seems like answered this very question in the process (this is one of those rare occasions where you answer two of your own questions with one answer posted by yourself). If you follow that other question, you'll see that it's indeed possible to define custom life times in Spring.NET.

So in summary, a custom lifetime in Spring.NET can be created by implementing the ITargetSource interface, though, arguably, it's a subtle interface and can be used to do fancy things around creating targets. There are already few implementations available including (but not limited to):

  • SingletonTargetSource (provides the singleton lifetime)
  • PrototypeTargetSource (provides the transient lifetime)
  • ThreadLocalTargetSource (provides thread-scoped lifetime)
  • SimplePoolTargetSource (provides object pooling)
  • HotSwappableTargetSource (provides the capability to swap targets at runtime)

Interestingly, applying a lifetime to your objects can be very different depending on what lifetime you want. All objects in Spring.NET are singleton by default. To specify an object as prototype (Spring.NET speak for transient), you set singleton="false" as follows:

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

Unfortunately, there's no such convenient property for the rest of the provided lifetimes (including your custom implementations). So, let's say you want to configure an object with thread-local scope. Here's how you'd do that using 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>

Again, if you want to achieve the exact same results as the above configuration but using DefaultAdvisorAutoProxyCreator, you'll have to do it in an entirely different way, including implementing a custom type that implements the ITargetSourceCreator interface.

Here's a bare bone ITargetSourceCreator implementation that creates a 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;
        }
    }
}

Finally, you need to use the following configuration to use the above ITargetSourceCreator with DefaultAdvisorAutoProxyCreator to create instances of your target type at thread-local scope:

<?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>

In my opinion, the way you configure lifetimes other than singleton (default) and prototype is somewhat non-intuitive and definitely not streamlined across different types of proxy factory implementations (ProxyFactoryObject vs. DefaultAdvisorAutoProxyCreator)

In summary, yes, Spring.NET does support custom lifetimes. If none of the predefined lifetimes meet your requirements, you can create a custom lifetime by implementing the ITargetSource interface and configuring it appropriately.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文