Java-бины? Весенние бобы Нах
Что такое весна?
Spring — это облегченная среда для Java, которая часто используется в корпоративной разработке, но не ограничивается ею. Spring является модульным, что означает, что вам нужно использовать только те пакеты, которые вы используете. Spring имеет несколько групп модулей Core, Web, Data Access и Miscellaneous. Spring позволяет инверсию управления (IoC) с помощью внедрения зависимостей (DI), это отделяет код и упрощает тестирование. Простота DI часто рассматривается как самое большое преимущество использования Spring. В Spring есть несколько терминов, специфичных для фреймворка, один из наиболее часто используемых терминов — bean.
Что такое весенняя фасоль?
Контейнеры
Прежде чем узнать о bean-компонентах, давайте посмотрим на контейнеры, в которых они используются. Контейнер Spring берет класс Java и некоторые метаданные конфигурации и создает приложение. Компоненты, передаваемые в контейнер, являются Spring Beans. Метаданные, предоставляемые контейнеру, могут быть заданы тремя различными способами: XML, аннотации и Java. Аннотации — это те, которые я чаще всего вижу в своей корпоративной рабочей среде. В Spring есть два типа контейнеров: BeanFactory
и ApplicationContext
. Bean factory — это более старый облегченный контейнер, обеспечивающий обратную совместимость. Контейнер ApplicationContext
обладает всеми функциями BeanFactory и даже больше, что делает его предпочтительным.
Что такое весенняя фасоль?
Spring Bean — это объект, созданный, собранный и управляемый контейнером Spring и созданный с использованием метаданных конфигурации, переданных этому контейнеру. https://www.tutorialspoint.com/spring/spring_bean_definition.htm
Это определение кажется мне слишком техническим и расплывчатым. Я предпочитаю определение, данное Элиасом Дорнелесом в этом посте о переполнении стека.
Спринг-бины — это всего лишь экземпляры объектов, которыми управляет контейнер Spring, а именно, они создаются и связываются фреймворком и помещаются в «мешок объектов» (контейнер), откуда вы можете получить их позже.
В Документации Spring также есть хорошее определение bean-компонентов. Описывая их как рецепт создания экземпляров класса, определенного этим определением компонента. Важно не путать Spring bean-компоненты с Javabeans. Oracle определяет Javabeans как POJO, реализующий интерфейс сериализации.
Бин Глубокое погружение
Теперь, когда мы знаем основы bean-компонента и контейнера Spring, давайте более подробно рассмотрим анатомию bean-компонента.
Объем компонента
Область действия компонента — это способ управления размером компонента. При определении bean-компонентов вы можете выбрать шесть вариантов области bean-компонентов. Четыре из этих областей действия компонента требуют использования веб-контейнера ApplicationContext
, поскольку они используют HTTP, сокеты и сервлеты для определения области действия компонента. Шесть областей: Singleton, Prototype, Request, Session, Application и WebSocket (последние 4 зависят от сети).
Синглтон — это область действия bean-компонента по умолчанию. Контейнер Spring создаст один экземпляр вашего компонента и кэширует его. Любые будущие запросы к компоненту будут возвращать кэшированный объект. Это отличается от шаблона проектирования singleton. Одноэлементный шаблон Gang of Four гарантирует, что объект создается только один раз в загрузчике классов. Spring привязывает синглтон к контейнеру. Ниже приведен пример метаданных XML для настройки этого параметра.
<bean id="badassService" class="com.foo.bar" scope="singleton"/>
Область прототипа будет создавать новый экземпляр bean-компонента каждый раз, когда есть запрос на bean-компонент. Общей практикой является использование синглетонов для объектов без состояния и прототипов для объектов с состоянием. Spring не будет очищать bean-компоненты с областью действия прототипа, разработчик должен справиться с очисткой.
<bean id="badassService" class="com.foo.bar" scope="prototype"/>
Одно замечание по поводу совместного использования singleton и bean-компонентов-прототипов. Если у вас есть компонент-одиночка с зависимостью от компонента-прототипа, прототип создается, а затем внедряется в синглтон. Прототип, который был создан, будет единственным экземпляром, который когда-либо будет передан одноэлементному компоненту.
Область запроса, сеанса и приложения создаст новый компонент для каждого HTTP-запроса/сеанса/веб-приложения. Когда отдельный запрос/сеанс/веб-приложение завершает обработку, экземпляр уничтожается. Вы можете закодировать это в XML так же, как в примерах кода, показанных выше, или использовать аннотации @RequestScope
, @SessionScope
или @ApplicationScope
в коде Java. Поскольку у вас может быть только одно приложение, область приложения ведет себя как одноэлементная область.
Жизненный цикл бобов
Существует три способа установки и удаления bean-компонента: аннотации, указание функции инициализации в XML или реализация интерфейсов Spring. Из трех методов лучше всего использовать аннотации или XML. Использование аннотаций позволяет отделить ваш код от необходимости реализовывать интерфейсы Spring.
Bean-компоненты имеют единый интерфейс для настройки и демонтажа. Для настройки реализуем метод InitializingBean
интерфейса afterPropertiesSet()
. Для демонтажа реализуйте метод DisposibleBean
destroy()
. Рекомендуемый способ сделать это — использовать аннотации @PostConstruct
и @PreDestroy
. Вызовы методов, несущих эти аннотации, происходят в той же точке жизненного цикла, что и afterPropertiesSet()
и destroy()
.
Initalization and Destroy using XML XML: <bean id="badassService" class="com.foo.bar" scope="prototype" init-method="intialize" destroy-method="clean"/> Java: public class Bar{ public void intialize(){ //This is my init method } public void clean(){ //this is my destroy method } }
В приведенном выше примере показано использование init-method
и destroy-method
в одном bean-компоненте, но если вы обнаружите, что используете одни и те же методы в нескольких классах Java, вы можете указать default-init-method
и default-destroy-method
на один уровень выше в поле beans
XML. Если у вас есть bean-компонент, имя которого не соответствует имени метода по умолчанию, этот bean-компонент может использовать init-method
для переопределения default-init-method
.
<beans default-init-method="intialize"> <bean id="badassService" class="com.foo.bar"></bean> </beans>
Если bean-компонент имеет несколько конфигураций для жизненного цикла, порядок следующий: аннотации, инициализация интерфейса Spring, затем пользовательские функции инициализации.
Наследование бобов
При использовании XML дочерние компоненты могут наследоваться от родительских компонентов с помощью атрибута parent
. Дочерние компоненты будут использовать класс родительского компонента, если не указана другая конфигурация. Дочерние компоненты унаследуют область действия, аргументы конструктора, значения свойств и переопределения методов родителя. Любая область действия, метод инициализации, метод уничтожения или статические фабричные методы, указанные в дочернем компоненте, будут переопределять настройки родительского компонента. Зависит от, авто-проводка, проверка зависимостей, синглтон и настройки отложенной инициализации всегда будут исходить из родительского компонента.
<bean id="badassParentService" class="com.foo.bar"></bean> <bean id="badassChildService" class="com.foo.childBar" parent="badassParentService"></bean>
Вывод
Весна - зверь, так многому нужно научиться и усвоить. В этой статье делается попытка объяснить важные части Spring bean-компонентов. Я начал с простого, а затем углубился в нюансы бобов по ходу статьи. Если какая-либо часть этой статьи не имеет смысла, я бы порекомендовал вернуться к последней части статьи и перечитать ее оттуда. Документация Spring — это всегда отличное место, где можно узнать больше, и, как всегда, Переполнение стека содержит множество вопросов и ответов по Spring. Если вам нужно больше информации, загляните в мой профиль и найдите статьи о Git, TypeScript и AWS.