如何覆盖Spring bean定义但仍然引用重写的bean?

时间:2010-03-13 06:24:30

标签: java spring

我正在尝试通过使用我的委托服务覆盖原始服务的bean定义来实现委托服务提供程序。但是,正如名称所暗示的那样,委托服务需要引用原始服务来委托调用。

我在使用原始bean def而不会遇到循环引用问题时,无法弄清楚如何覆盖bean定义。

例如:

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

这可能吗?

5 个答案:

答案 0 :(得分:11)

您的问题的简短回答是您不能拥有两个具有相同名称的bean定义。如果您尝试,则会隐藏另一个,只有一个定义可用。

您的问题示例似乎表明您正在尝试将原始service bean包装在代理对象中,并且包装器会围绕对服务的调用执行一些前后工作。实现此目的的一种方法是在不定义两个service bean的情况下,并且不修改原始service bean,使用Spring AutoProxyCreator,可能是BeanNameAutoProxyCreator

这允许您列出要自动代理的bean(或bean)。您可以指定要应用于目标bean上的调用的拦截器。您将实施这些拦截器来完成您需要做的工作。

Spring会自动为您创建一个委托代理,它的bean标识为service,但具有附加功能。

答案 1 :(得分:2)

您可以创建proxies and interceptors。所以现在名为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>

答案 2 :(得分:1)

听起来你正试图重新发明spring-AOP。请考虑使用spring-AOP。

可以以编程方式更改现有服务的名称,并使用旧名称创建一个新bean。 spring框架内的autoproxying-code执行此操作,您可以查看它。在Spring框架中快速搜索 Auto Proxy *应该可以帮助您。

或者,如果您控制客户端站点(使用者),则可以向包装器添加限定符,并使用限定符来强制对消费者执行正确的实现。包装器可以使用非限定的实现来访问原始的。 (也可以通过在xml代码中添加一个限定符来为服务添加另一个bean定义,将限定符重新装载到原始实现中,但是没有尝试过,但它应该可以工作)

答案 3 :(得分:1)

将“ref”元素的“parent”属性与父容器一起使用 您可以在Spring文档中找到详细的示例:http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-ref-element

答案 4 :(得分:0)

写了一篇关于如何做得很好的博客文章: http://www.solubris.com/blog/overriding_spring_context_for_testing

使用通配符上下文定义意味着您不需要使用导入。

当您想要重新定义具有相同ID的相同bean时,Parent不起作用。