Я пытаюсь реализовать Поставщика услуг делегата путем переопределения бобового определения для исходного сервиса с моим Сервисом делегата. Однако, поскольку имя подразумевало бы, для Сервиса делегата нужна ссылка на исходный сервис для делегирования вызовов к.
Я испытываю затруднения при выяснении, как переопределить бобовое определение при использовании исходного бобового определения, не сталкиваясь с проблемой циклической ссылки.
Например:
<!-- Original service def in spring-context.xml -->
<bean id="service" class="com.mycompany.Service"/>
<!-- Overridden definition in spring-plugin-context.xml -->
<bean id="service" class="com.mycompany.DelegatedService"/>
<constructor-arg ref="service"/>
</bean>
Действительно ли это возможно?
Короткий ответ на ваш вопрос заключается в том, что вы не можете иметь два определения bean с одинаковым именем. Если вы попытаетесь, одно из них скроет другое, и только одно определение будет пригодно для использования.
Пример вашего вопроса, похоже, предполагает, что вы пытаетесь обернуть оригинальный service
bean в прокси-объект, при этом обертка выполняет некоторую работу до и после вызовов сервиса. Один из способов достичь этого, не определяя два боба service
и не изменяя исходный боб service
, - это использовать Spring AutoProxyCreator
, возможно, BeanNameAutoProxyCreator
.
Это позволяет вам перечислить боб (или бобы), которые должны быть автоматически проксированы. Вы указываете перехватчики, которые вы хотите применять к вызовам целевого боба. Вы реализуете эти перехватчики для выполнения нужной вам работы.
Spring автоматически создаст для вас делегирующий прокси, который будет иметь идентификатор боба service
, как и раньше, но с вашей дополнительной функциональностью.
Вы можете создавать прокси и перехватчики . Итак, теперь bean-компонент с именем service
станет прокси-сервером для исходной службы
, которую необходимо переименовать во что-то другое. Таким образом, изменения будут ограничены только Spring XML и не будут распространяться на ваш Java-код.
<bean id="personTarget" class="com.mycompany.PersonImpl">
<property name="name"><value>Tony</value></property>
<property name="age"><value>51</value></property>
</bean>
<bean id="myAdvisor" class="com.mycompany.MyAdvisor">
<property name="someProperty"><value>Custom string property value</value></property>
</bean>
<bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor">
</bean>
<bean id="person"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.mycompany.Person</value></property>
<property name="target"><ref local="personTarget"/></property>
<property name="interceptorNames">
<list>
<value>myAdvisor</value>
<value>debugInterceptor</value>
</list>
</property>
</bean>
Похоже, вы пытаетесь заново изобрести Spring-AOP. Пожалуйста, подумайте об использовании для этого Spring-AOP.
Можно программно изменить имя существующей службы и создать новый компонент со старым именем. Код автопроксификации внутри Spring framework делает это, и вы можете взглянуть на это. Быстрый поиск кода для Auto Proxy * в среде Spring должен помочь вам.
В качестве альтернативы, если вы управляете клиентскими сайтами (потребителями), вы можете добавить квалификатор в свою оболочку и использовать квалификаторы для принуждения потребителей к правильным реализациям. Оболочка может использовать неквалифицированную реализацию для получения доступа к оригиналу. (Также возможно ретро-монтирование квалификатора к исходной реализации, добавив другое определение bean-компонента для службы с квалификатором в xml-коде, который вы контролируете, не пробовал, но это должно работать)
Используйте атрибут "parent" элемента "ref" с родительским контейнером.
Вы можете найти подробный пример в документации Spring: http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-ref-element