Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

spring

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 imply, the delegate Service needs a reference to the original service to delegate calls to.

I'm having trouble figuring out how to override the bean definition while using the original bean def without running into a circular reference issue.

For example:

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

Is this possible?

like image 659
Kevin Avatar asked Mar 13 '10 06:03

Kevin


People also ask

How do I override a Spring bean?

The most common approach followed for overriding a spring bean is to define a new bean, with the same id as the original bean, in a separate XML file. During context initialization, Spring would register the last bean found for the id, and use it for all the injections.

Does Spring allow more than one bean definition in the configuration?

Spring Couldn't autowired,there is more than one bean of `` type. Bookmark this question.

What is the correct way to load bean definitions from another file?

Just import the xml defining the bean with <import resource="otherXml. xml"> and you will be able to use the bean definition.

What is the default bean ID if you only use bean How can you override this?

When using @Bean without specifying name or alias, the default bean ID will be created based on the name of the method which was annotated with @Bean annotation. You can override this behaviour by specifying name or aliases for the bean. Alias is always the second name of the bean.


2 Answers

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.

like image 192
skaffman Avatar answered Sep 27 '22 20:09

skaffman


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>
like image 42
saugata Avatar answered Sep 27 '22 22:09

saugata