Spring IoC контейнер: Java конфигурация, объединение конфигурации Java и XML

Поддержка класса @Configuration в Spring не ставит своей целью полностью заменить Spring XML. Некоторые средства, такие как пространства имен Spring XML, остаются идеальным способом настройки контейнера. В тех случаях, когда XML удобен или необходим, у вас есть выбор: либо создать экземпляр контейнера "XML-ориентированным" способом, используя, например, ClassPathXmlApplicationContext, либо создать его "Java-ориентированным" способом, используя AnnotationConfigApplicationContext и аннотации @ImportResource для импорта XML по мере необходимости.

XML-ориентированное использование классов @Configuration

Может быть предпочтительнее загружать контейнер Spring из XML и включать классы @Configuration в специальном режиме. Например, в большой существующей кодовой базе, которая использует Spring XML, проще создавать классы @Configuration по мере необходимости и включать их из существующих файлов XML.

Объявление классов @Configuration как простых элементов Spring <bean/>

Помните, что классы @Configuration в конечном итоге являются определениями bean-компонентов в контейнере. В примерах этой серии мы создаем класс @Configuration с именем AppConfig и включаем его в system-test-config.xml как определение <bean/>. Поскольку <context:annotation-config/> включен, контейнер распознает аннотацию @Configuration и правильно обрабатывает методы @Bean, объявленные в AppConfig.

В следующем примере показан обычный класс конфигурации в Java:

Java

@Configuration
public class AppConfig {

    @Autowired
    private DataSource dataSource;

    @Bean
    public AccountRepository accountRepository() {
        return new JdbcAccountRepository(dataSource);
    }

    @Bean
    public TransferService transferService() {
        return new TransferService(accountRepository());
    }
}

Kotlin

@Configuration
class AppConfig {

    @Autowired
    private lateinit var dataSource: DataSource

    @Bean
    fun accountRepository(): AccountRepository {
        return JdbcAccountRepository(dataSource)
    }

    @Bean
    fun transferService() = TransferService(accountRepository())
}

В следующем примере показана часть образца файла system-test-config.xml:

<beans>
    <!-- включить обработку аннотаций, таких как @Autowired и @Configuration -->
    <context:annotation-config/>
    <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>

    <bean class="com.acme.AppConfig"/>

    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

В следующем примере показан возможный файл jdbc.properties:

jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
jdbc.username=sa
jdbc.password=

Java

public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/com/acme/system-test-config.xml");
    TransferService transferService = ctx.getBean(TransferService.class);
    // ...
}

Kotlin

fun main() {
    val ctx = ClassPathXmlApplicationContext("classpath:/com/acme/system-test-config.xml")
    val transferService = ctx.getBean<TransferService>()
    // ...
}

В файле system-test-config.xml AppConfig <bean/> не объявляет элемент id. Хотя это было бы приемлемо, в этом нет необходимости, учитывая, что никакой другой компонент никогда не ссылается на него, и вряд ли он будет явно извлечен из контейнера по имени. Точно так же bean-компонент DataSource всегда автоматически подключается по типу, поэтому явный идентификатор bean-компонента не требуется.

Использование <context:component-scan/> для выбора классов @Configuration

Поскольку @Configuration имеет мета-аннотацию с помощью @Component, классы с @Configuration автоматически становятся кандидатами для сканирования компонентов. Используя тот же сценарий, который описан в предыдущем примере, мы можем переопределить system-test-config.xml, чтобы воспользоваться преимуществами сканирования компонентов. Обратите внимание, что в этом случае нам не нужно явно объявлять <context:annotation-config/>, потому что <context:component-scan/> включает ту же функциональность.

В следующем примере показан измененный файл system-test-config.xml:

<beans>
    <!-- принимает и регистрирует AppConfig как определение bean -->
    <context:component-scan base-package="com.acme"/>
    <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>

    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки