какие типы конфигурации поддерживает spring

Инициализация Spring: XML, аннотации, Java конфигурация и … Groovy

В настоящий момент Spring framework поддерживает четыре разных способа конфигурирования контекста, каждый из которых заслуживает отдельного рассмотрения.

Подготовка

Я создал многомодульный maven проект, с различными подмодулями для каждого варианта конфигурирования контекста. За основу каждого модуля я взял код примера Hello, Spring! и изменил его соответствующим образом.

Исторически конфигурирование контекста c использованием XML было первым методом конфигурирования, появившемся в Spring.

Конфигурирование с помощью XML заключается в создании xml файла (традиционно носящего названия вида «context.xml», «applicationContext.xml» и т.д.), описывающего Spring beans, процесс их создания и взаимосвязи между ними. Поэтому в первую очередь убедимся, что в коде отсутствуют аннотации @Service и @Inject и сразу после их удаления напишем им замену в xml:

Файл «/resource/applicationContext.xml» заменяет и класс ContextConfiguration и аннотации.

Вначале мы определили бин «coin», передав ему в конструктор внутренний анонимный бин, созданный из java.util.Random. Связывание было проведено по типу аргумента, а передаваемый в конструктор бин был определён на месте.

Бин «coin» используется в следующем определении. GreeterTargetImpl требует, чтобы ему передали экземпляр Coin и мы его передаём. Причём в этот раз передаём его как параметр номер 0 и, вместо создания бина на месте, мы ссылаемся на ранее определённый бин с именем «coin».

Бин «greeter» демонстрирует третий метод передачи параметров — по имени переменной.

Кроме параметров конструктора в xml конфиге можно сразу устанавливать значения свойств, методы вызываемые при инициализации бина, использовать фабрики для создания экземпляров бинов, но всему этому я посвящу отдельную статью, а пока обойдусь простым примером:

name = «coin» ref = «coin» />

В приложении заменим создание контекста на ClassPathXmlApplicationContext ( «/applicationContext.xml» ) и можно проверять результат:

Использованием XML конфигурации конечно неудобно тем, что приходится кроме написания непосредственно кода описывать ещё и его использование в Spring, при этом не имея возможности проверить ошибки в конфигурации до запуска тестов (или даже приложения). Кроме того, в декларативном xml файле достаточно сложно реализовать конфигурацию, требующую активных действий во время создания контекста.

С другой стороны, xml конфигурация представляет собой централизованное описание приложения, которое может хранится отдельно от кода, позволяя менять структуру приложения без пересборки. С помощью xml можно использовать в качестве Spring beans сторонний код. И, что для кого-то может оказаться важным, в коде отсутствуют специфичные для Spring вещи.

Annotations

Конфигурирование Spring context с помощью аннотаций уже рассматривалось в Hello, Spring!, но полезно будет попробовать аннотации в чистом виде.

К коду оригинального примера добавится ещё один класс:

Код интеграционного теста придётся сильно изменить. Дело в том, что в настоящий момент @ConfigurationContext не поддерживает annotation-only конфигурацию, поэтому приходится использовать костыль:

Конечно, использование аннотаций для определения бинов и их зависимостей, весьма удобно и упрощает разработку, но недостатков у этого подхода больше всего. Конфигурация контекста получается децентрализованной, так что неосторожное добавление нового бина может внезапно изменить работу всего приложения (и это, опять таки, не узнать до запуска тестов/приложения). Так же в код попадают Spring специфичные вещи, которые потом могут затруднить смену платформы. С аннотациями использование стороннего кода либо невозможно, либо требует определённых подпорок и костылей. Кроме того, единственной возможностью изменить поведение приложения будет его пересборка.

Java configuration

Третий подход — программное создание бинов, реализующий модный принцип convention over configuration, соглашения по конфигурации. Стоит отметить, что под программным созданием бинов я понимаю создание бинов на стадии формирования контекста, а не после того, как приложение уже запущено.

Важно и название класса конфигурации: несмотря на искушение назвать конфигурационный класс Context, делать этого не следует. Дело в том, что Spring создаст бин и из этого класса, а в качестве имени использует имя класса. А имя «Context» уже занято самим Spring.

Java конфигурация выглядит наилучшим образом, если сравнивать её достоинства и недостатки. Это и централизованность как в xml; и безопасность типов; и простой рефакторинг; и отсутствия spring специфичных вещей в коде; и возможность выполнения каких-либо действий на этапе конфигурации. К недостаткам, пожалуй, относится необходимость ручного создания бинов и необходимость пересборки для переконфигурации приложения.

Groovy

Поддержка Groovy скриптов и специального beans DSL появилась в четвёртой версии Spring как попытка сделать конфигурацию вообще без недостатков. Groovy конфигурация должна объединить в себе достоинства XML конфигурации и Java конфигурации, оставаясь дружественной к аннотациям.

Чтобы попробовать groovy конфигурацию, необходимо добавить groovy runtime в приложение:

Источник

Spring изнутри. Этапы инициализации контекста

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

Доброго времени суток уважаемые хабравчане. Уже 3 года я работаю на проекте в котором мы используем Spring. Мне всегда было интересно разобраться с тем, как он устроен внутри. Я поискал статьи про внутреннее устройство Spring, но, к сожалению, ничего не нашел.

Всех, кого интересует внутреннее устройство Spring, прошу под кат.

На схеме изображены основные этапы поднятия ApplicationContext. В этом посте мы остановимся на каждом из этих этапов. Какой-то этап будет рассмотрен подробно, а какой-то будет описан в общих чертах.

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

1. Парсирование конфигурации и создание BeanDefinition

Цель первого этапа — это создание всех BeanDefinition. BeanDefinition — это специальный интерфейс, через который можно получить доступ к метаданным будущего бина. В зависимости от того, какая у вас конфигурация, будет использоваться тот или иной механизм парсирования конфигурации.

Xml конфигурация

Для Xml конфигурации используется класс — XmlBeanDefinitionReader, который реализует интерфейс BeanDefinitionReader. Тут все достаточно прозрачно. XmlBeanDefinitionReader получает InputStream и загружает Document через DefaultDocumentLoader. Далее обрабатывается каждый элемент документа и если он является бином, то создается BeanDefinition на основе заполненных данных (id, name, class, alias, init-method, destroy-method и др.). Каждый BeanDefinition помещается в Map. Map хранится в классе DefaultListableBeanFactory. В коде Map выглядит вот так.

Конфигурация через аннотации с указанием пакета для сканирования или JavaConfig

Конфигурация через аннотации с указанием пакета для сканирования или JavaConfig в корне отличается от конфигурации через xml. В обоих случаях используется класс AnnotationConfigApplicationContext.

Если заглянуть во внутрь AnnotationConfigApplicationContext, то можно увидеть два поля.

ClassPathBeanDefinitionScanner сканирует указанный пакет на наличие классов помеченных аннотацией @Component (или любой другой аннотацией которая включает в себя @Component). Найденные классы парсируются и для них создаются BeanDefinition.
Чтобы сканирование было запущено, в конфигурации должен быть указан пакет для сканирования.

Groovy конфигурация

Данная конфигурация очень похожа на конфигурацию через Xml, за исключением того, что в файле не XML, а Groovy. Чтением и парсированием groovy конфигурации занимается класс GroovyBeanDefinitionReader.

2. Настройка созданных BeanDefinition

После первого этапа у нас имеется Map, в котором хранятся BeanDefinition. Архитектура спринга построена таким образом, что у нас есть возможность повлиять на то, какими будут наши бины еще до их фактического создания, иначе говоря мы имеем доступ к метаданным класса. Для этого существует специальный интерфейс BeanFactoryPostProcessor, реализовав который, мы получаем доступ к созданным BeanDefinition и можем их изменять. В этом интерфейсе всего один метод.

Метод postProcessBeanFactory принимает параметром ConfigurableListableBeanFactory. Данная фабрика содержит много полезных методов, в том числе getBeanDefinitionNames, через который мы можем получить все BeanDefinitionNames, а уже потом по конкретному имени получить BeanDefinition для дальнейшей обработки метаданных.

Давайте разберем одну из родных реализаций интерфейса BeanFactoryPostProcessor. Обычно, настройки подключения к базе данных выносятся в отдельный property файл, потом при помощи PropertySourcesPlaceholderConfigurer они загружаются и делается inject этих значений в нужное поле. Так как inject делается по ключу, то до создания экземпляра бина нужно заменить этот ключ на само значение из property файла. Эта замена происходит в классе, который реализует интерфейс BeanFactoryPostProcessor. Название этого класса — PropertySourcesPlaceholderConfigurer. Весь этот процесс можно увидеть на рисунке ниже.

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

Давайте еще раз разберем что же у нас тут происходит. У нас имеется BeanDefinition для класса ClassName. Код класса приведен ниже.

Если PropertySourcesPlaceholderConfigurer не обработает этот BeanDefinition, то после создания экземпляра ClassName, в поле host проинжектится значение — «$» (в остальные поля проинжектятся соответсвующие значения). Если PropertySourcesPlaceholderConfigurer все таки обработает этот BeanDefinition, то после обработки, метаданные этого класса будут выглядеть следующим образом.

Соответственно в эти поля проинжектятся правильные значения.

Для того что бы PropertySourcesPlaceholderConfigurer был добавлен в цикл настройки созданных BeanDefinition, нужно сделать одно из следующих действий.

Для XML конфигурации.

PropertySourcesPlaceholderConfigurer обязательно должен быть объявлен как static. Без static у вас все будет работать до тех пор, пока вы не попробуете использовать @ Value внутри класса @Configuration.

3. Создание кастомных FactoryBean

На первый взгляд, тут все нормально и нет никаких проблем. А что делать если нужен другой цвет? Создать еще один бин? Не вопрос.

А что делать если я хочу каждый раз случайный цвет? Вот тут то и приходит на помощь интерфейс FactoryBean.

Создадим фабрику которая будет отвечать за создание всех бинов типа — Color.

Добавим ее в xml и удалим объявленные до этого бины типа — Color.

Теперь создание бина типа Color.class будет делегироваться ColorFactory, у которого при каждом создании нового бина будет вызываться метод getObject.

Для тех кто пользуется JavaConfig, этот интерфейс будет абсолютно бесполезен.

4. Создание экземпляров бинов

Созданием экземпляров бинов занимается BeanFactory при этом, если нужно, делегирует это кастомным FactoryBean. Экземпляры бинов создаются на основе ранее созданных BeanDefinition.

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

5. Настройка созданных бинов

Интерфейс BeanPostProcessor позволяет вклиниться в процесс настройки ваших бинов до того, как они попадут в контейнер. Интерфейс несет в себе несколько методов.

Процесс донастройки показан на рисунке ниже. Порядок в котором будут вызваны BeanPostProcessor не известен, но мы точно знаем что выполнены они будут последовательно.

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

Для того, что бы лучше понять для чего это нужно, давайте разберемся на каком-нибудь примере.

При разработке больших проектов, как правило, команда делится на несколько групп. Например первая группа разработчиков занимается написанием инфраструктуры проекта, а вторая группа, используя наработки первой группы, занимается написанием бизнес логики. Допустим второй группе понадобился функционал, который позволит в их бины инжектить некоторые значения, например случайные числа.

На первом этапе будет создана аннотация, которой будут помечаться поля класса, в которые нужно проинжектить значение.

По умолчанию, диапазон случайных числе будет от 0 до 10.

Затем, нужно создать обработчик этой аннотации, а именно реализацию BeanPostProcessor для обработки аннотации InjectRandomInt.

Код данного BeanPostProcessor достаточно прозрачен, поэтому мы не будем на нем останавливаться, но тут есть один важный момент.

BeanPostProcessor обязательно должен быть бином, поэтому мы его либо помечаем аннотацией @Component, либо регестрируем его в xml конфигурации как обычный бин.

Первая группа разработчиков свою задачу выполнила. Теперь вторая группа может использовать эти наработки.

В итоге, все бины типа MyBean, получаемые из контекста, будут создаваться с уже проинициализированными полями value1 и value2. Также тут стоить отметить, этап на котором будет происходить инжект значений в эти поля будет зависеть от того какой @ Scope у вашего бина. SCOPE_SINGLETON — инициализация произойдет один раз на этапе поднятия контекста. SCOPE_PROTOTYPE — инициализация будет выполняться каждый раз по запросу. Причем во втором случае ваш бин будет проходить через все BeanPostProcessor-ы что может значительно ударить по производительности.

Полный код программы вы можете найти тут.

Хочу сказать отдельное спасибо EvgenyBorisov. Благодаря его курсу, я решился на написание этого поста.

Также советую посмотреть его доклад с JPoint 2014.

Источник

Spring: в поисках контекста

Пару месяцев назад в моем профиле был опубликован подробный пост по загрузке классов на JVM. После этого доклада мои коллеги задались хорошим вопросом: а какой механизм использует Spring для разбора конфигураций и как он загружает классы из контекста?

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

После многих часов дебага спринговых исходников мой коллега экспериментальным путём докопался до той самой простой и понятной правды.

Немного теории

Сразу определим, что ApplicationContext — это главный интерфейс в Spring-приложении, который предоставляет информацию о конфигурации приложения.

Перед тем, как перейти непосредственно к демонстрации, взглянем на этапы формирования ApplicationContext:

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

В этом посте разберем первый этап, так как нас интересует именно чтение конфигураций и создание BeanDefinition.

BeanDefinition — это интерфейс, который описывает бин, его свойства, аргументы конструктора и другую метаинформацию.

Что касается конфигурации самих бинов, у Spring есть 4 способа конфигурации:

Xml конфигурация

За основу берем простой проект:

Здесь следует немного пояснить, какие методы и для чего используются:

В 25 строке идет объявление и инициализация ApplicationContext через конфигурацию Xml.

Конфигурационный Xml-файл выглядит следующим образом:

При конфигурации бина указываем реально существующий class. Обратите внимание на заданное свойство lazy-init=”true”: в этом случае бин будет создаваться только после запроса его из контекста.

Смотрим, как Spring при поднятии контекста разрулит ситуацию с классами, объявленными в конфигурационном файле:

Разберемся с деталями Xml конфигурации:

— Чтением файла конфигурации занимается класс XmlBeanDefinitionReader, который реализует интерфейс BeanDefinitionReader;

XmlBeanDefinitionReader на входе получает InputStream и загружает Document через DefaultDocumentLoader:

— После этого каждый элемент этого документа обрабатывается и, если он является бином, создается BeanDefinition на основе заполненных данных (id, name, class, alias, init- method, destroy-method и др.):

— Каждый BeanDefinition помещается в Map, который хранится в классе DefaultListableBeanFactory:

В коде Map выглядит следующим образом:

Теперь в том же конфигурационном файле добавим еще одно объявление бина с классом film.BadVillain:

Смотрим, что получится, если распечатать список созданных BeanDefenitionNames и загруженные классы:

Несмотря на то, что класса film.BadVillain, указанного в конфигурационном файле, не существует, Spring отрабатывает без ошибок:

Cписок BeanDefenitionNames содержит 2 элемента; то есть, те 2
BeanDefinition, сконфигурированные в нашем файле, были созданы.

Конфигурации обоих бинов, по сути, одинаковы. Но, при этом существующий класс загрузился, никаких проблем не возникло. Из чего можно сделать вывод, что попытка загрузить несуществующий класс также была, но провальная попытка ничего не сломала.

Попытаемся получить еще и сами бины по их именам:

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

Если в первом случае был получен валидный бин, то во втором случае прилетел exception.

Обратите внимание на stack trace: сработала отложенная загрузка классов. Выполняется обход всех загрузчиков классов в попытке найти искомый класс среди загруженных ранее. И после того, как нужный класс не был найден, с помощью вызова метода Utils.forName, происходит попытка найти несуществующий класс по имени, что привело к получению закономерной ошибки.

При поднятии контекста загрузился только один класс, при этом попытка загрузки несуществующего файла не привела к ошибке. Почему так произошло?

Всё потому, что мы прописали lazy-init:true и запретили Spring создавать экземпляр бина, где и генерируется полученный ранее exception. Если убрать это свойство из конфигурации либо изменить его значение lazy-init:false, то описанная выше ошибка также вылетит, но не будет проигнорирована и приложение остановиться. В нашем случае контекст был проинициализирован, но мы не смогли создать экземпляр бина, т.к. указанный класс не был найден.

Groovy конфигурация

При конфигурации контекста с помощью Groovy-файла, необходимо сформировать GenericGroovyApplicationContext, который принимает на вход строку с конфигурацией контекста. Чтением контекста в данном случае занимается класс GroovyBeanDefinitionReader. Эта конфигурация работает по сути так же, как и Xml, только с Groovy-файлами. К тому же, GroovyApplicationContext нормально работает и с Xml-файлом.

Пример простого конфигурационного Groovy-файла:

Пробуем проделать то же самое, что и с Xml:

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

Ошибка вылетает сразу: Groovy так же, как и Xml, создает BeanDefenition’ы, но в данном случае постпроцессор сразу выдаёт ошибку.

Конфигурация через аннотации с указанием пакета для сканирования или JavaConfig

Данная конфигурация отличается от двух предыдущих. В конфигурация через аннотации используется 2 варианта: JavaConfig и аннотация над классами.

Здесь используется один и тот же контекст: AnnotationConfigApplicationContext(“package”/JavaConfig.class). Работает он в зависимости от того, что было передано в конструктор.

В контексте AnnotationConfigApplicationContext есть 2 приватных поля:

Создаем конфигурационный файл с максимально простым бином. Смотрим, что загрузится:

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

Если в случае с Xml и Groovy загрузилось столько BeanDefinition, сколько было объявлено, то в данном случае в процессе поднятия контекста загружаются как объявленные, так и дополнительные BeanDefinition. В случае реализации через JavaConfig все классы загружаются сразу, в том числе и класс самого JavaConfig, так как он сам является бином.

Еще один момент: в случае с Xml и Groovy конфигурациями загрузилось 343 файла, здесь же произошла более “тяжелая” загрузка количеством 631 доп файл.

Этапы работы ClassPathBeanDefinitionScanner:

Рассмотрим работу сканера на простом примере.

Создаем собственную аннотацию для поиска соответствующих классов:

Создаем 2 класса: один со стандартной аннотацией Component, второй — с кастомной аннотацией:

В результате получаем сформированные BeanDefinition для этих классов и успешно загруженные классы.

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает spring

Вывод

Из всего вышесказанного на поставленные вопросы можно ответить следующим образом:

Источник

Spring JavaConfig Reference Guide

Rod Johnson

Costin Leau

Chris Beams

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

Preface

Spring Java Configuration (JavaConfig) provides a pure-Java means of configuring the Spring IoC container. By taking advantage of Java 5.0 language features such as annotations and generics, JavaConfig allows users to express configuration logic and metadata directly in code, alleviating any need for XML.

By relying only on basic Java syntax and language features, JavaConfig offers several distinct advantages:

To get a sense of how to use JavaConfig, let’s configure an application consisting of two beans:

Bootstrapping this application would then be as simple as the following:

While this example is a trivial one, JavaConfig can flex to meet the needs of the most complex and sophisticated enterprise applications. This guide will show you how.

1. Introduction

1.1. What this guide covers

This guide covers all aspects of Spring JavaConfig. It covers implementing and using @Configuration classes to configure the Spring IoC container and working with the feature set. It also covers extending and customizing JavaConfig.

1.1.1. Topics not covered

If general aspect oriented programming (AOP) concepts are unfamiliar, or AOP with Spring and AspectJ 5’s @Aspect style are unfamiliar, it is recommended that you first read Chapter 6. AOP from the Core Spring Framework documentation.

1.2. What JavaConfig requires to run

Spring 2.5.6 or higher

AspectJ 1.6.2 or higher

1.3. Where to get support

Professional from-the-source support for Spring JavaConfig is available from SpringSource, the company behind Spring.

1.4. Where to follow development

You can provide feedback and help make JavaConfig best serve the needs of the Spring community by interacting with the developers at the Spring JavaConfig Community Forum.

Report bugs and influence the JavaConfig project roadmap using Spring’s JIRA issue tracker.

Browse JavaConfig sources and subscribe to RSS commit feeds using the Spring’s FishEye service.

Stay tuned to Continuous Integration and nightly snapshot build status using Spring’s Bamboo service.

Subscribe to the Spring Community Portal and SpringSource Team Blog for the latest Spring news and announcements, including information on Spring JavaConfig releases.

1.5. How to retrieve and build JavaConfig from source

You must have Java 5.0 (or better) and Ant 1.7.0 (or better) installed to build JavaConfig from source.

.1. Publishing JavaConfig artifacts to a local Maven repository

1.6. How to import JavaConfig as an Eclipse project

The project should now be imported, error-free and ready for development.

1.7. How to obtain milestone builds

1.7.1. Via manual download

Milestone builds are available from Spring’s milestone build area.

1.7.2. Via Maven

To access milestone builds using Maven, add the following repositories to your Maven pom:

Then add the following dependency:

1.7.3. Via Ivy

To access milestone builds using Ivy, add the following repositories to your Ivy config:

Then declare the following dependency:

1.8. How to obtain nightly (aka ‘snapshot’) builds

1.8.1. Via manual download

Nightly builds are available from Spring’s snapshot build area.

1.8.2. Via Maven

To access nightly builds using Maven, add the following repositories to your Maven pom:

Then add the following dependency:

1.8.3. Via Ivy

To access nightly builds using Ivy, add the following repositories to your Ivy config:

Then declare the following dependency:

2. Authoring @Configuration classes

2.1. @Configuration

Annotating a class with the @Configuration indicates that the class may be used by JavaConfig as a source of bean definitions. The simplest possible @Configuration class would read as follows:

Because the semantics of the attributes to the @Configuration annotation are 1:1 with the attributes to the element, this documentation defers to the beans-definition section of Chapter 3, IoC from the Core Spring documentation. See also the Javadoc for @Configuration for details on each of the available annotation attributes.

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает springTip
Jump to Section 3.1, “ Bootstrapping applications with JavaConfigApplicationContext ” to see how @Configuration classes are used to create a Spring Application Context.

2.2. @Bean

2.2.1. Declaring a bean

For comparison sake, the configuration above is exactly equivalent to the following Spring XML:

2.2.2. Injecting dependencies

When @Bean s have dependencies on one another, expressing that dependency is as simple as having one bean method call another:

In the example above, the foo bean recevies a reference to bar via constructor injection.

2.2.3. Receiving lifecycle callbacks

2.2.3.1. Using JSR-250 annotations

JavaConfig, like the core Spring Framework, supports use of JSR-250 «Common Annotations». For example:

2.2.3.2. Using Spring interfaces

2.2.3.3. Using @Bean initMethodName / destroyMethodName attributes

The @Bean annotation supports specifying arbitrary initialization and destruction callback methods, much like Spring XML’s init-method and destroy-method attributes to the bean element:

Of course, in the case of Foo above, it would be equally as valid to call the init() method directly during construction:

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает springTip
Remember that because you are working directly in Java, you can do anything you like with your objects, and do not always need to rely on the container!

2.2.4. Using *Aware interfaces

If the class above were declared as a bean as follows:

2.2.5. Specifying bean scope

2.2.5.1. Using @Bean ‘s scope attribute

JavaConfig makes available each of the four standard scopes specified in Section 3.4, «Bean Scopes» of the Spring reference documentation.

The DefaultScopes class provides string constants for each of these four scopes. SINGLETON is the default, and can be overridden by supplying the scope attribute to @Bean annotation:

2.2.5.2. @ScopedProxy

Spring offers a convenient way of working with scoped dependencies through scoped proxies. The easiest way to create such a proxy when using the XML configuration is the element. JavaConfig offers equivalent support with the @ScopedProxy annotation, which provides the same semantics and configuration options.

If we were to port the the XML reference documentation scoped proxy example (see link above) to JavaConfig, it would look like the following:

2.2.5.3. Lookup method injection

As noted in the core documentation, lookup method injection is an advanced feature that should be comparatively rarely used. It is useful in cases where a singleton-scoped bean has a dependency on a prototype-scoped bean. JavaConfig provides a natural means for implementing this pattern. Note that the example below is adapted from the example classes and configuration in the core documentation linked above.

JavaConfig can easily create a subclass of CommandManager where the abstract createCommand() is overridden in such a way that it ‘looks up’ a brand new (prototype) command object:

2.2.6. Customizing bean naming

By default, JavaConfig uses a @Bean method’s name as the name of the resulting bean. This functionality can be overridden, however, using the BeanNamingStrategy extension point.

JavaConfigApplicationContext will be covered in detail in Chapter 3, Using @Configuration classes

2.2.7. Working with Spring FactoryBean implementations

The Spring container recognizes that LocalSessionFactoryBean implements the FactoryBean interface, and thus treats this bean specially: An instance of LocalSessionFactoryBean is instantiated, but instead of being directly returned, instead the getObject() method is invoked. It is the object returned from this call getObject() that is ultimately registered as the sessionFactory bean.

How then would we use LocalSessionFactoryBean in JavaConfig? The best approach is to extend the ConfigurationSupport base class and use the getObject() method:

3. Using @Configuration classes

3.1. Bootstrapping applications with JavaConfigApplicationContext

3.1.1. Construction Options

Instantiating the JavaConfigApplicationContext can be done by supplying @Configuration class literals to the constructor, and/or strings representing packages to scan for @Configuration classes.

3.1.1.1. Construction by class literal

Each of the class literals supplied to the constructor will be processed, and for each @Bean method encountered, JavaConfig will create a bean definition and ultimately instantiate and initialize the bean.

Passing multiple @Configuration classes:

3.1.1.2. Construction by base package

Base packages will be scanned for the existence of any @Configuration classes. Any candidate classes will then be processed much as if they had been supplied directly as class literals to the constructor.

Passing multiple base packages:

Matching packages and classes by wildcard:

The wildcard syntax for matching packages and classes above is based on Ant Patterns

3.1.1.3. Post-construction configuration

3.1.2. Accessing beans with getBean()

JavaConfigApplicationContext provides several variants of the getBean() method for accessing beans.

3.1.2.1. Type-safe access

The preferred method for accessing beans is with the type-safe getBean() method.

Disambuguation options

If more than one bean of type Service had been defined in the example above, the call to getBean() would have thrown an exception indicating an ambiguity that the container could not resolve. In these cases, the user has a number of options for disambiguation:

Indicating a @Bean as primary

Like Spring’s XML configuration, JavaConfig allows for specifying a given @Bean as primary :

After this modification, all calls to getBean(Service.class) will return the primary bean

Disambiguation by bean name

JavaConfig provides a getBean() variant that accepts both a class and a bean name for cases just such as these.

Because bean ids must be unique, this call guarantees that the ambiguity cannot occur.

Retrieve all beans of a given type

It is also reasonable to call the getBeansOfType() method in order to return all beans that implement a given interface:

Note that this latter approach is actually a feature of the Core Spring Framework’s AbstractApplicationContext (which JavaConfigApplicationContext extends) and is not type-safe, in that the returned Map is not parameterized.

3.1.2.2. String-based access

Beans may be accessed via the traditional string-based getBean() API as well. Of course this is not type-safe and requires casting, but avoids any potential ambiguity entirely:

3.2. Bootstrapping web applications with JavaConfigWebApplicationContext

JavaConfigWebApplicationContext allows for seamlessly bootstrapping @Configuration classes within your servlet container’s web.xml deployment descriptor. This process requires no Spring XML whatsoever:

4. Modularizing configurations

While the simplest configuration may be expressed as a single class that exposes several beans, it is often desirable to modularize configurations for reuse and clarity.

4.1. Partitioning bean definitions into multiple @Configuration classes

The simplest technique for modularizing configurations is to split up a single @Configuration class into multiple smaller classes:

The above configuration class might be supplied as a parameter to JavaConfigApplicationContext :

We can easily partition this configuration such that bean definitions are spread across two classes, instead of one:

Now simply supply both configuration classes to the constructor of JavaConfigApplicationContext :

4.2. Referencing beans across @Configuration classes

One configuration class may need to reference a bean defined in another configuration class (or in XML, for that matter). The preferred mechanism for doing this is using Spring’s @Autowired annotation:

4.2.1. Direct bean references with @Autowired

One @Configuration class may directly reference bean instances registered from another using Spring’s @Autowired annotation.

4.2.2. Fully-qualified bean references with @Autowired

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает springTip
The ‘fully-qualified’ approach is generally preferred as it provides a the significant advantage of being able to easily navigate within an IDE to the source of the referenced bean.

Open issue: Should @AnnotationDrivenConfig be enabled by default? Rationale: given that @Autowired is the preferred method for referencing external beans, it is likely to need to be enabled in all but the most trivial configurations. See SJC-219.

4.3. Aggregating @Configuration classes with @Import

The @Import annotation provides just this kind of support, and it is the direct equivalent of the element found in Spring beans XML files.

Multiple configurations may be imported by supplying an array of classes to the @Import annotation

4.4. ConfigurationSupport

5. Working with externalized values

5.1. @ExternalValue

Externally defined values such as usernames, passwords, file paths, and the like may be accessed using @ExternalValue and one or more of JavaConfig’s ValueSource annotations.

5.1.1. @ExternalValue fields

com/acme/db.properties will be read from the classpath and the value associated with key datasource.username will be injected into the username field. The contents of db.properties might be as follows:

5.1.2. @ExternalValue methods

@ExternalValue may also be used as a method-level annotation

The primary advantage to using @ExternalValue methods is that rather than injecting the external value just once (as is done in the case of @ExternalValue fields), @ExternalValue methods are evaluated every time they’re referenced. As this is not usually required, @ExternalValue fields are the preferred method. A downside of @ExternalValue methods is that they should be abstract, requiring you to declare the entire @Configuration class abstract, and this is not in alignment with the semantics users typically associate with using the abstract keyword.

5.2. Available ValueSource annotations

ValueSource annotations may be used in conjunction:

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает springNote
Explicit ordering of ValueSource annotations is not yet supported but will be soon. See SJC-170 and SJC-171 for details.

6. Combining configuration styles

JavaConfig can be used in conjunction with any or all of Spring’s other container configuration approaches.

6.1. JavaConfig and XML

6.1.1. Bootstrapping JavaConfig from XML with ConfigurationPostProcessor

Then, bootstrap an XML ApplicationContext:

6.1.1.1. Configuring configurations

An added benefit that comes along with bootstrapping JavaConfig from XML is that the configuration bean instances are eligible, just as any other bean, for dependency injection:

6.1.2. Bootstrapping XML from JavaConfig with @ImportXml

The @ImportXml annotation is provided to support importing beans defined in XML into @Configuration classes.

6.2. JavaConfig and Annotation-Driven Configuration

6.2.1. @AnnotationDrivenConfig

In JavaConfig, this same functionality is enabled with the @AnnotationDrivenConfig annotation

6.2.2. @ComponentScan

An equivalent for Spring XML’s is provided with the @ComponentScan annotation.

With the above very minimal configuration in the Config class, we can bootstrap and use the application as follows:

Please see «Chapter 3, IoC» of the core spring documentation for additional detail on Annotation-Driven Injection support.

7. Transaction-management support

7.1. @AnnotationDrivenTx

JavaConfig provides full support for the annotation-driven declarative transaction management features provided by the core Spring Framework with the @AnnotationDrivenTx annotation:

Like Spring XML’s element, @AnnotationDrivenTx expects the presence of a bean named transactionManager of type PlatformTransactionManager as in the example above. Should you wish to forego this convention and name a transaction manager bean another name, you may do as follows:

The other attributes available to the @AnnotationDrivenTx are similar to the attributes to the element. See the related documentation and the JavaDoc for @AnnotationDrivenTx for details.

8. AOP support

8.1. @AspectJAutoProxy

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает springNote
The attributes to the @AspectJAutoProxy annotation are very similar to the attributes to the element. See the related documentation and the JavaDoc for @AspectJAutoProxy for details.

9. JMX support

9.1. @MBeanExport

As an equivalent to Spring XML’s element, JavaConfig provides the @MBeanExport annotation.

10. Testing support

10.1. JavaConfigContextLoader

какие типы конфигурации поддерживает spring. Смотреть фото какие типы конфигурации поддерживает spring. Смотреть картинку какие типы конфигурации поддерживает spring. Картинка про какие типы конфигурации поддерживает spring. Фото какие типы конфигурации поддерживает springNote
Unfortunately, due to compatibility constraints with the TestContext framework’s @ContextConfiguration annotation, the fully-qualified classname for com.bank.TransferAppConfig must be expressed as a string. This has a negative effect on refactorability, and will be improved in the future if possible. Vote for SJC-238 if this improvement is important to you.

11. Extending JavaConfig

11.1. @Plugin

Similar to Spring 2.0’s support for XML namespaces, JavaConfig provides an extensibility mechanism with the @Plugin annotation. The general intent is to allow for a more expressive and declarative way to register commonly used bean definitions.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *