OKAN
OKAN

Reputation: 421

Overriding Spring bean

I have the following scenario:

  1. Spring project A with multiple bean configurations, including a bean named "searchHelper":
    <bean name="searchHelper" class="com.test.SearchHelperImpl"/>
    where SearchHelperImpl implements "SearchHelper" interface
  2. Spring project B depends on A with a custom SearchHelperBImpl

What I was thinking of making is just copying the whole configuration into the new project and changing what needs to be changed, but that's not convenient and there must be an easier way of doing this.

My question is, how do I override the definition of the "searchHelper" bean to use SearchHelperBImpl instead of SearchHelperImpl? I want to use the same bean name in order for everything that uses this name to use the new implementation. I am using Spring 3.2.2

Thanks

Upvotes: 9

Views: 13314

Answers (3)

informatik01
informatik01

Reputation: 16406

NOTE
This answer relates to how to avoid duplicate bean definitions. For overriding see the answer by nicholas.hauschild.


More effective solution to avoid copying is to place all the beans that are common for both projects in a separate XML configuration file, say "common-beans.xml". And in the configuration XML file for the project B (and any other project that needs those beans) you import that file like this:

<import resource="common-beans.xml" />


Simple example

example-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
    
    <!-- 
         Assuming common-beans.xml is a Spring config file
         that contains the definitions you need to use
         in the current project. 
    -->
    <import resource="common-beans.xml" />
    
    <!-- Defining a bean with the implementaion you need -->
    <bean name="searchHelper" class="com.test.SearchHelperBImpl"/>
    
    <!-- Some other configurations if needed -->
    
</beans>

Useful reading:

Upvotes: 2

digitaljoel
digitaljoel

Reputation: 26574

One interesting "feature" (some consider it a bug) of Spring is that a bean with the same name declared later in configuration will override a bean declared earlier in configuration. So if your project B depends on A, and the configuration in A is included in B, and B defines a bean by the same name after the A configuration then the B instance will "win" and that's the instance you will get.

I would not recommend depending on this behavior, but would go with the answer regarding the Primary annotation. I just thought I would bring this up so you would be aware that even without the primary, or in case the one in project A is also primary you would know that the latest definition wins.

Upvotes: 7

nicholas.hauschild
nicholas.hauschild

Reputation: 42834

You should be able to utilize the primary xml attribute on your bean element.

<bean name="searchHelper" primary="true" class="com.test.SearchHelperBImpl"/>

Alternatively, if you are using JavaConfig, you can utilize the @Primary annotation.

@Primary
@Bean
public SearchHelper searchHelper() {
    return new SearchHelperBImpl();
}

Upvotes: 10

Related Questions