Overriding Spring Beans with Aliases


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.

I dislike this approach for two reasons.

  1. It needs the bean ids to be same, thereby taking away the flexibility to provide a meaningful id to the new bean.
  2. It demands that the XML with the new bean is loaded last and enforces the developers to define them last in the context location. This can lead to errors if not careful. 

There is an alternate approach, which I prefer. Overriding the bean through aliases. The following set of steps explains this approach.

First, define the bean that needs to be overridden.
<bean id="defaultTxnProcessorBean" class="com.thespringthing.TransactionProcessor">
    ..
    </bean>
    
    

Define a property placeholder, for the properties file that would be used to set the overriding bean name.
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="location" >
          <value>classpath:config.properties</value>
       </property>
    </bean>
    
    

Next, create an alias for the bean, with a configurable name. Default the value of the property to the default bean name, so that Spring does not enforce creation of this properties file or if the property file already exists then defining this property in the file.
<alias name="${txnprocessor.name:defaultTxnProcessorBean}" alias="txnProcessorBean"/>

Inject this bean to other beans, using the alias.
<bean id="anyotherbean" class="com.thespringthing.XYZ">
       <property name="txnProcessor" ref="txnProcessorBean" />
    </bean>
    
    


Now, let's say you need to override the default txnProcessor bean, then define the new bean.
<bean id="newTxnProcessorBean" class="com.thespringthing.NewTxnProcessor">
    ..
    </bean>
    
    

In the config.properties set the property to the new bean name.
txnprocessor.name=newTxnProcessorBean


This would set the alias to the new bean and would use it for injection, thereby overriding the default bean.