1

DefaultAdvisorAutoProxyCreator を使用して (インターセプターを使用して) スレッド ローカル オブジェクトを作成したいと考えています。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 を使用して同じ効果を得る方法がわかりません。これが私が試したことです(しかしうまくいきませんでした):

<?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 インスタンスを返すカスタム クラスです。

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 を要求すると、スレッドごとにオブジェクトのインスタンスが 1 つだけ取得されます (正しい動作)。ただし、2 番目の構成 (DefaultAdvisorAutoProxyCreator) では、毎回新しいインスタンスを取得します (動作が正しくありません。スレッドごとに 1 つのインスタンスが必要です)。

何かご意見は?

4

2 に答える 2

0

テストされていませんが、これ(またはそのようなもの)を試してください:

protected override AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name, IObjectFactory factory) {
  ThreadLocalTargetSource ts = new ThreadLocalTargetSource();
  ts.TargetObjectName = name;
  ts.ObjectFactory = factory;
  return ts;
}
于 2012-02-15T07:43:40.127 に答える
0

わかりました。なぜ期待どおりに機能しなかったのかがわかりました。ばかげているようですが、AbstractPrototypeTargetSourceCreator.GetTargetSource()からThreadLocalTargetSourceの新しいインスタンスを作成して返していました。もちろん、ThreadLocalTargetSourceの新しい各インスタンスには、以前に「cousins」によって作成された既存のターゲットインスタンスの手がかりがないため、インスタンスが要求されるたびに、ターゲットの新しいインスタンスが作成されます。

解決は非常に簡単でした。ITargetSourceCreatorの実装を更新して、ThreadLocalTargetSourceの単一インスタンスを作成し、AbstractPrototypeTargetSourceCreator.GetTargetSource()が呼び出されるたびにそのインスタンスを返すようにしました。

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;
        }
    }
}

このコードを使用すると、完全に機能し、プロキシされたオブジェクトのスレッドローカルライフタイムを取得できます。

于 2012-02-17T03:16:08.500 に答える