如何在 Spring.NET 中使用 DefaultAdvisorAutoProxyCreator 定义线程范围的对象 [英] How to Define Thread-scoped objects with DefaultAdvisorAutoProxyCreator in Spring.NET
问题描述
我想使用 DefaultAdvisorAutoProxyCreator 创建一个线程本地对象(带有拦截器).我知道如何使用 ProxyFactoryObject 做到这一点:
I want to create a thread-local object (with interceptors) using DefaultAdvisorAutoProxyCreator. I know how to 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" singleton="false">
<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>
但是,我不知道如何使用 DefaultAdvisorAopCreator 获得相同的效果.这是我尝试过的(但没有用):
However, I don't know how to get the same effect using DefaultAdvisorAopCreator. Here's what I tried (but didn't work):
<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net">
<object id="ConsoleLoggingBeforeAdvisor" 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="CustomTargetSourceCreators">
<list element-type="Spring.Aop.Framework.AutoProxy.ITargetSourceCreator">
<object id="ThreadLocalTargetSourceCreator" type="Spring.Examples.AopQuickStart.ThreadLocalTargetSourceCreator"/>
</list>
</property>
</object>
</objects>
ThreadLocalTargetSourceCreator 是一个自定义类,它无条件返回一个 ThreadLocalTargetSource 实例:
ThreadLocalTargetSourceCreator is a custom class that unconditionally returns a ThreadLocalTargetSource instance:
namespace Spring.Examples.AopQuickStart {
public class ThreadLocalTargetSourceCreator : AbstractPrototypeTargetSourceCreator {
protected override AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name, IObjectFactory factory) {
return new ThreadLocalTargetSource();
}
}
}
所以,总而言之,当我使用第一个配置(使用 ProxyFactoryObject)从 Spring.NET 请求 ServiceCommand 时,我只得到每个线程的一个对象实例(正确的行为).但是,使用第二个配置 (DefaultAdvisorAutoProxyCreator),我每次都会得到一个新实例(错误的行为;每个线程期望一个实例).
So, in summary, when I request ServiceCommand from Spring.NET with the first config (using ProxyFactoryObject), I get only one instance of the object per thread (correct behavior). However, with the second config (DefaultAdvisorAutoProxyCreator), I get a new instance every time (incorrect behavior; expecting one instance per thread).
有什么想法吗?
推荐答案
好的,我找到了它没有按预期工作的原因.看起来很愚蠢,我正在从 AbstractPrototypeTargetSourceCreator.GetTargetSource() 创建并返回 ThreadLocalTargetSource 的新实例.当然,ThreadLocalTargetSource 的每个新实例都不知道它的堂兄弟"之前创建的任何现有目标实例,因此每次请求实例时它都会创建其目标的新实例.
Ok, I found out why it was not working as expected. Silly as it seems, I was creating and returning a new instance of ThreadLocalTargetSource from AbstractPrototypeTargetSourceCreator.GetTargetSource(). Of course, each new instance of ThreadLocalTargetSource would have no clue of any existing target instances created by its "cousins" before, so it would create a new instance of its target every time an instance was requested.
解决方法很简单.我刚刚更新了 ITargetSourceCreator 的实现,以确保它创建了 ThreadLocalTargetSource 的单个实例并在每次调用 AbstractPrototypeTargetSourceCreator.GetTargetSource() 时返回该实例:
The resolution was very simple. I just updated my implementation of ITargetSourceCreator to make sure it created a single instance of ThreadLocalTargetSource and returned that instance each time AbstractPrototypeTargetSourceCreator.GetTargetSource() was called:
namespace Spring.Examples.AopQuickStart {
public class ThreadLocalTargetSourceCreator : AbstractPrototypeTargetSourceCreator {
private readonly ThreadLocalTargetSource _threadLocalTargetSource;
public ThreadLocalTargetSourceCreator() {
_threadLocalTargetSource = new ThreadLocalTargetSource();
}
protected override AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name, IObjectFactory factory) {
return _threadLocalTargetSource;
}
}
}
使用此代码,它非常适合我,并且我的代理对象获得了线程本地生命周期.
With this code, it works perfectly for me and I get a thread-local life time for my proxied objects.
这篇关于如何在 Spring.NET 中使用 DefaultAdvisorAutoProxyCreator 定义线程范围的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!