1. Обзор
Бин — ключевая концепция Spring Framework. Поэтому понимание этого понятия имеет решающее значение для понимания структуры и эффективного ее использования.
К сожалению, нет четких ответов на простой вопрос о том, что на самом деле представляет собой bean-компонент Spring. Некоторые объяснения доходят до такого низкого уровня, что общая картина упускается из виду, тогда как другие слишком расплывчаты.
В этом руководстве мы попытаемся пролить свет на эту тему, начиная с описания в официальной документации.
2. Определение компонента
Вот определение bean-компонентов в документации Spring Framework :
В Spring объекты, формирующие основу вашего приложения и управляемые контейнером Spring IoC, называются bean-компонентами. Компонент — это объект, который создается, собирается и иным образом управляется контейнером Spring IoC.
Это определение является кратким и точным, но не раскрывает важный элемент: контейнер Spring IoC. Давайте подробнее рассмотрим, что это такое и какие преимущества оно приносит.
3. Инверсия управления
Проще говоря, инверсия управления (IoC) — это процесс, в котором объект определяет свои зависимости, не создавая их. Этот объект делегирует работу по созданию таких зависимостей контейнеру IoC.
Прежде чем углубляться в IoC, начнем с объявления нескольких классов предметной области.
3.1. Классы домена
Предположим, у нас есть объявление класса:
public class Company {
private Address address;
public Company(Address address) {
this.address = address;
}
// getter, setter and other properties
}
Этому классу нужен соавтор типа Address
:
public class Address {
private String street;
private int number;
public Address(String street, int number) {
this.street = street;
this.number = number;
}
// getters and setters
}
3.2. Традиционный подход
Обычно мы создаем объекты с помощью конструкторов их классов:
Address address = new Address("High Street", 1000);
Company company = new Company(address);
В этом подходе нет ничего плохого, но не было бы неплохо лучше управлять зависимостями?
Представьте себе приложение с десятками или даже сотнями классов. Иногда мы хотим использовать один экземпляр класса во всем приложении, иногда нам нужен отдельный объект для каждого варианта использования и так далее.
Управление таким количеством объектов — не что иное, как кошмар. Здесь на помощь приходит инверсия управления.
Вместо того, чтобы создавать зависимости самостоятельно, объект может извлекать свои зависимости из контейнера IoC. Все, что нам нужно сделать, это предоставить контейнеру соответствующие метаданные конфигурации.
3.3. Конфигурация компонента
Во-первых, давайте украсим класс Company аннотацией
@Component
:
@Component
public class Company {
// this body is the same as before
}
Вот класс конфигурации, предоставляющий метаданные bean-компонента в контейнер IoC:
@Configuration
@ComponentScan(basePackageClasses = Company.class)
public class Config {
@Bean
public Address getAddress() {
return new Address("High Street", 1000);
}
}
Класс конфигурации создает bean-компонент типа Address
. Он также содержит аннотацию @ComponentScan
, которая указывает контейнеру искать bean-компоненты в пакете, содержащем класс Company .
Когда контейнер Spring IoC создает объекты этих типов, все объекты называются bean-компонентами Spring, поскольку они управляются контейнером IoC.
3.4. ИОК в действии
Поскольку мы определили bean-компоненты в классе конфигурации, нам понадобится экземпляр класса AnnotationConfigApplicationContext
для создания контейнера :
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Быстрый тест проверяет существование и значения свойств наших bean-компонентов:
Company company = context.getBean("company", Company.class);
assertEquals("High Street", company.getAddress().getStreet());
assertEquals(1000, company.getAddress().getNumber());
Результат доказывает, что контейнер IoC правильно создал и инициализировал bean-компоненты.
4. Вывод
В этой статье дано краткое описание компонентов Spring и их связи с контейнером IoC.
Полный исходный код можно найти на GitHub .