Spring IoC
IoC — Inversion of Control, так же известное как Dependency Injection (DI) — процесс, согласно которому объекты определяют свои зависимости, т.е. объекты, с которыми они работают, через аргументы конструктора/фабричного метода или свойства, которые были установлены или возвращены фабричным методом. Затем контейнер inject(далее "внедряет") эти зависимости при создании бина. Этот процесс принципиально противоположен, поэтому и назван Inversion of Control, т.к. бин сам контролирует реализацию и расположение своих зависимостей, используя прямое создание классов или такой механизм, как шаблон Service Locator.
Основными пакетами Spring Framework IoC контейнера являются org.springframework.beans
и org.springframework.context
. Интерфейс BeanFactory
предоставляет механизм конфигурации по управлению любым типом объектов. ApplicationContext
- наследует нитерфейс BeanFactory
и добавляет более специфичную функциональность.
Замечение: Аннотации @Autowired
, @Inject
, @Resource
и @Value
обрабатываются Spring реализацией BeanPostProcessor
, поэтому вы не можете их применять в своих собственных BeanPostProcessor
и BeanFactoryPostProcessor
, а только лишь явной инициализацией через XML или @Bean
метод.
Настройка IoC контейнера
@Configuration & @Bean
Основными признаками и частями Java-конфигурации IoC контейнера являются классы с аннотацией @Configuration
и методы с аннотацией @Bean
. Аннотация @Bean
используется для указания того, что метод создает, настраивает и инициализирует новый объект, управляемый Spring IoC контейнером. Такие методы можно использовать как в классах с аннотацией @Configuration
, так и в классах с аннотацией @Component
(или её наследниках). Класс с аннотацией @Configuration
говорит о том, что он является источником определения бинов. Самая простейшая из возможных конфигураций выглядит следующим образом:
Для того, чтобы приступить к настройке и изучению Spring IoC контейнера, вы должны инициализировать ApplicationContext
, который поможет также с разрешением зависимостей. Для обычной Java-конфигурации применяется AnnotationConfigApplicationContext
, в качестве аргумента к которому передается класс, либо список классов с аннотацией @Configuration
, либо с любой другой аннотацией JSR-330, в том числе и @Component
:
@Import
Большая часть приложений строится по модульной архитектуре, разделенная по слоям, например DAO, сервисы, контроллеры и др. Создавая конфигурацию, можно также её разбивать на составные части, что также улучшит читабельность и панимание архитектуры вашего приложения. Для этого в конфигурацию необходимо добавить аннотацию @Import
, в параметрах которой указываются другие классы с аннотацией @Configuration
, например:
Таким образом, при инициализации контекста вам не нужно дополнительно указывать загрузку из конфигурации AnotherConfiguration
, все останется так, как и было:
@Autowired
В большинстве случаев, имеются такие случаи, когда бин в одной конфигурации имеет зависимость от бина в другой конфигурации. Поскольку конфигурация является источником определения бинов, то разрешить такую зависимость не является проблемой, достаточно объявить поле класса конфигурации с аннотацией @Autowired
(более подробно описано в отдельной главе):
@Profile и @Conditional
Это способ сказать SpringBoot, какой из бинов подгрузить при определенных условиях. Подробнее в статье с Хабра.
Реализуя интерфейс Condition, можно настроить свои правила определения бинов, например, зарегистрировать один бин, если еще не зарегистрирован другой:
XML конфигурации
Классы с аннотацией @Configuration
не стремятся на 100% заменить конфигурации на XML, при этом, если вам удобно или имеется какая-то необходимость в использовании XML конфигурации, то к вашей Java-конфигурации необходимо добавить аннотацию @ImportResource
, в параметрах которой необходимо указать нужное вам количество XML-конфигураций. Выглядит это следующим способом:
Last updated