Как определить объекты в области потоков с помощью DefaultAdvisorAutoProxyCreator в Spring.NET

Я хочу создать объект локального потока (с перехватчиками) с помощью 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();
        }
    }
}

Итак, в итоге, когда я запрашиваю ServiceCommand из Spring.NET с первой конфигурацией (с использованием ProxyFactoryObject), я получаю только один экземпляр объекта на поток (правильное поведение). Однако со второй конфигурацией (DefaultAdvisorAutoProxyCreator) я каждый раз получаю новый экземпляр (неправильное поведение; ожидание одного экземпляра на поток).

Есть предположения?


person ehsanullahjan    schedule 15.02.2012    source источник


Ответы (2)


Не проверял, но попробуйте это (или что-то в этом роде):

protected override AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name, IObjectFactory factory) {
  ThreadLocalTargetSource ts = new ThreadLocalTargetSource();
  ts.TargetObjectName = name;
  ts.ObjectFactory = factory;
  return ts;
}
person bbaia    schedule 15.02.2012
comment
Добавление этого кода не обязательно в реализации ITargetSourceCreator, поскольку метод AbstractPrototypeTargetSourceCreator.GetTargetSource () устанавливает свойства TargetObjectName и ObjectFactory в экземпляре ITargetSource, возвращаемом моей реализацией метода AbstractPrototypeTargetSourceCreator.CreatePrototype). Есть другие мысли? - person ehsanullahjan; 16.02.2012

Хорошо, я узнал, почему он не работает должным образом. Как это ни глупо, я создавал и возвращал новый экземпляр ThreadLocalTargetSource из AbstractPrototypeTargetSourceCreator.GetTargetSource (). Конечно, каждый новый экземпляр ThreadLocalTargetSource не будет иметь никаких сведений о каких-либо существующих целевых экземплярах, созданных его «кузенами» ранее, поэтому он будет создавать новый экземпляр своей цели каждый раз, когда запрашивается экземпляр.

Решение было очень простым. Я только что обновил свою реализацию 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;
        }
    }
}

С этим кодом он отлично работает у меня, и я получаю время жизни локального потока для моих проксируемых объектов.

person ehsanullahjan    schedule 17.02.2012