Spring Framework широко используется в качестве контейнера для внедрения зависимостей, и это по веским причинам. Прежде всего, это облегчает интеграционное тестирование и дает нам возможность настраивать создание и инициализацию bean-компонента (например, @Autowired для типов List ).
Но есть и очень полезная функция, которая может быть упущена из виду, поэтому давайте обсудим псевдонимы bean-компонентов .
Псевдонимы компонентов позволяют нам переопределять уже настроенные компоненты и заменять их определением другого объекта. Это наиболее полезно, когда определения bean-компонентов наследуются от внешнего ресурса, который находится вне нашего контроля.
В следующем примере я покажу вам, как работает псевдонимы bean-компонентов. Давайте начнем со следующего определения bean-компонента, взятого из файла конфигурации src / main / resources / spring / applicationContext-tx.xml .
Этот контекстный файл содержит множество функций, связанных с транзакциями / JPA, которые мы хотели бы использовать в наших интеграционных тестах.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
<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"/> |
Определение bean-компонента dataSource предполагает наличие источника данных XA, но, поскольку HSQLDB не предоставляет его, я вынужден полагаться на LrcXADataSource для преодоления этого ограничения. Но это подразумевает изменение источника данных для использования другого className и driverProperties, и мы не можем этого сделать, так как определение контекста происходит от внешнего артефакта.
К счастью, здесь на помощь приходит псевдоним бобов. Вот как наш контекст Integration Testing src / test / resources / spring / applicationContext-test.xml использует эту удобную функцию:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
<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"/> |
TestDataSource относится к тому же типу Class, что и унаследованный dataSource, но поставляется с другой конфигурацией объекта. Это источник данных, который мы хотели бы использовать каждый раз, когда требуется зависимость dataSource, вместо исходного варианта. Это возможно с помощью ключевого слова alias, которое указывает контейнеру внедрения зависимостей заменить исходное определение источника данных новой версией.