Enterprise Java

Why I like Spring bean aliasing

Spring framework is widely used as a dependency injection container, and that’s for good reasons. First of all, it facilitates integration testing and it gives us the power of customizing bean creation and initialization (e.g. @Autowired for List types).

But there is also a very useful feature, that might get overlooked and therefore let’s discuss about bean aliasing.

Bean aliasing allows us to override already configured beans and to substitute them with a different object definition. This is most useful when the bean definitions are inherited from an external resource, which is out of our control.

In the following example I will show you how bean aliasing works. Let’s start with the following bean definition, coming from the src/main/resources/spring/applicationContext-tx.xml configuration file.

This context file contains many transaction/JPA related features we would like to use in our Integration Tests.

<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close">
	<property name="className" value="${jdbc.driverClassName}"/>
	<property name="uniqueName" value="dataSource"/>
	<property name="minPoolSize" value="0"/>
	<property name="maxPoolSize" value="5"/>
	<property name="allowLocalTransactions" value="false" />
	<property name="driverProperties">
		<props>
			<prop key="user">${jdbc.username}</prop>
			<prop key="password">${jdbc.password}</prop>
			<prop key="url">${jdbc.url}</prop>
		</props>
	</property>
</bean>

<bean id="jtaTransactionManager" factory-method="getTransactionManager"
	class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig, dataSource"
	destroy-method="shutdown"/>

The dataSource bean definition expects a XA Datasource, but since HSQLDB doesn’t provide one, I have to rely on LrcXADataSource to overcome this limitation. But this implies changing the dataSource to use a different className and driverProperties, and we cannot do that, since the context definition comes from an external artifact.

Luckily, this is where bean aliasing comes to the rescue. This is how our Integration Testing context src/test/resources/spring/applicationContext-test.xml makes use of this handy feature:

<import resource="classpath:spring/applicationContext-tx.xml" />

<bean id="testDataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close">
	<property name="className" value="bitronix.tm.resource.jdbc.lrc.LrcXADataSource"/>
	<property name="uniqueName" value="testDataSource"/>
	<property name="minPoolSize" value="0"/>
	<property name="maxPoolSize" value="5"/>
	<property name="allowLocalTransactions" value="false" />
	<property name="driverProperties">
		<props>
			<prop key="user">${jdbc.username}</prop>
			<prop key="password">${jdbc.password}</prop>
			<prop key="url">${jdbc.url}</prop>
			<prop key="driverClassName">${jdbc.driverClassName}</prop>
		</props>
	</property>
</bean>

<alias name="testDataSource" alias="dataSource"/>

The testDataSource is of the same Class type with the inherited dataSource, but it comes with a different object configuration. This is the data source we would like to use every time a dataSource dependency is required, instead of the original variant. This is possible through the alias keyword, that’s instructing the dependency injection container to replace the original dataSource definition with the new version.
 

Reference: Why I like Spring bean aliasing from our JCG partner Vlad Mihalcea at the Vlad Mihalcea’s Blog blog.

Vlad Mihalcea

Vlad Mihalcea is a software architect passionate about software integration, high scalability and concurrency challenges.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button