代码之家  ›  专栏  ›  技术社区  ›  Kevin

如何重写一个spring bean定义,但仍然引用被重写的bean?

  •  10
  • Kevin  · 技术社区  · 14 年前

    我试图通过使用委托服务重写原始服务的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 回复  |  直到 14 年前
        1
  •  11
  •   skaffman    14 年前

    对您的问题的简短回答是,不能有两个同名的bean定义。如果您尝试,其中一个将隐藏另一个,并且只有一个定义可用。

    你的问题的例子似乎表明你在试图把原来的 service 代理对象中的bean,包装器在处理服务调用之前和之后执行一些操作。实现这一目标的一种方法,而不必定义两种 服务 豆子,并且不修改原始的 服务 豆豆,就是用弹簧 AutoProxyCreator ,可能是 BeanNameAutoProxyCreator .

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

    spring会自动为您创建一个委托代理,它将具有bean id 服务 和以前一样,但是有了额外的功能。

        2
  •  2
  •   saugata    14 年前

    你可以创建 proxies and interceptors . 所以现在这个豆子 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>
    
        3
  •  1
  •   krosenvold    14 年前

    听起来你是想重新发明Spring AOP。请考虑使用spring aop进行此操作。

    可以通过编程更改现有服务的名称,并使用旧名称创建新的bean。spring框架中的自动代理代码可以做到这一点,您可以查看一下。快速代码搜索 汽车 spring框架中的proxy*应该可以帮助您实现这一点。

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

        4
  •  1
  •   Oded Peer    14 年前

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

        5
  •  0
  •   Solubris    11 年前

    写了一篇关于如何做到这一点的博文: http://www.solubris.com/blog/overriding_spring_context_for_testing

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

    当您想用相同的id重新定义同一个bean时,parent不起作用。