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.