How do I override a Spring bean definition yet still reference the overridden bean?

后端 未结 5 771
忘了有多久
忘了有多久 2020-12-29 13:03

I\'m attempting to implement a delegate Service provider by overriding the bean definition for the original service with my delegate Service. However, as the name would imp

相关标签:
5条回答
  • 2020-12-29 13:35

    Use the "parent" attribute of the "ref" element with a parent container.
    You can find a detailed example in Spring documentation: http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-ref-element

    0 讨论(0)
  • 2020-12-29 13:45

    You can create proxies and interceptors. So now the bean named service will become a proxy to the original service which needs to be renamed to something else. So the changes will be limited to the Spring XML only and not be propagated to your java code.

    <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>
    
    0 讨论(0)
  • 2020-12-29 13:52

    The short answer to your question is that you cannot have two bean definitions with the same name. If you try, one will hide the other, and only one definition will be usable.

    Your question's example seems to suggest that you're trying to wrap the original service bean in a proxy object, with the wrapper performing some before-and-after work around calls to the service. One way to achieve this, without defining two service beans, and without modifying the original service bean, is to use a Spring AutoProxyCreator, probably a BeanNameAutoProxyCreator.

    This allows you to list a bean (or beans) that are to be automatically proxied. You specify the interceptors you want to be applied to invocations on the target bean. You would implement these interceptors to do the work you need to do.

    Spring would automatically create a delegating proxy for you, which would have the bean id service as before, but with your additional functionality.

    0 讨论(0)
  • 2020-12-29 13:56

    It sounds like you're trying to reinvent spring-AOP. Please consider using spring-AOP for this.

    It's possible to programatically change the name of the existing service and create a new bean with the old name. The autoproxying-code inside spring framework does this and you could have a look at that. A quick code search for AutoProxy* in the spring framework should get you there.

    Alternately if you control the client sites (the consumers), you could add a qualifier to your wrapper, and use qualifiers to coerce the proper implementations to the consumers. The the wrapper could use the unqualified implemementation to get access to the original. (It might also be possible to retro-mount a qualifier to the original implementation by adding another bean definition for service with a qualifier in xml code that you control, haven't tried this but it should work)

    0 讨论(0)
  • Have written a blog post on how to do this nicely: http://www.solubris.com/blog/overriding_spring_context_for_testing

    Using wildcard context definitions means you don't need to use imports.

    Parent doesn't work when you want to redefine the same bean with the same id.

    0 讨论(0)
提交回复
热议问题