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, которое указывает контейнеру внедрения зависимостей заменить исходное определение источника данных новой версией.