В Spring Bean является самым основным объектом, и все операции выполняются вокруг Bean. Spring — это фреймворк BOP (Bean Oriented Programming).Роль Bean-компонентов в BOP такая же, как и роль объектов в ООП. Поскольку это так важно, нам сначала нужно понять, что такое bean?
что такое фасоль
Во-первых, давайте взглянем на определение bean-компонентов в официальной документации Spring:
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application
Как видно из вышеизложенного, мы можем дать Bean определение:Bean就是由IOC实例化、组装、管理的一个对象
.
Жизненный цикл фасоли
Нам нужно четко понимать, что жизненный цикл нашего Бина здесь в основном относится кsingleton bean
, Для bean-компонента-прототипа, когда пользователь getBean получает экземпляр bean-прототипа, контейнер IOC больше не управляет текущим экземпляром, а передает право управления пользователю, а затем getBean генерирует новый экземпляр. Мы не будем говорить о бинах таких областей, как запрос/сеанс/приложение/вебсокет.
В разных контейнерах жизненный цикл Бина начинается в разное время. Для ApplicationContext экземпляр bean-компонента уже создан при запуске контейнера. А для BeanFactory, до звонкаgetBean()
создается экземпляр метода.
Мы знаем, что для обычных java-объектов их жизненный цикл
- создавать экземпляр
- Перерабатывать через механизм сборки мусора, когда он больше не используется
Но не для Бина. Жизненный цикл Bean показан на следующем рисунке.
Для вышеуказанных методов мы можем разделить их на следующие категории
-
Bean自身的方法
: такие как конструкторы, геттеры/сеттеры и методы, указанные init-method и destroy-method и т. д. -
Bean级生命周期方法
: это можно понимать как метод, который класс Bean непосредственно реализует интерфейс, например BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean и другие методы, эти методы действуют только на текущий Bean -
容器级的方法(BeanPostProcessor一系列接口)
: в основном методы постпроцессора, такие как методы интерфейса InstantiationAwareBeanPostProcessor и BeanPostProcessor на рисунке выше. Классы реализации этих интерфейсов не зависят от bean-компонента и будут зарегистрированы в контейнере Spring. Эти постпроцессоры вступают в игру, когда контейнер Spring создает любой компонент. -
工厂后处理器方法(BeanFactoryProcessor一系列接口)
: включая AspectJWeavingEnabler, CustomAutowireConfigurer, ConfigurationClassPostProcessor и т. д. Это все BeanFactoryPostProcessors, которые были реализованы в среде Spring для реализации некоторых конкретных функций.
Собственные методы бина и методы жизненного цикла на уровне бина действительны только для当前Bean
работает, но методы жизненного цикла на уровне контейнера и методы фабричного постпроцессора所有的bean
оба работают
Для этих типов методов хорошо понятны 1 2 4. Давайте сосредоточимся на том, что такое BeanPostProcessor и BeanFactoryPostProcessor.
В моем личном понимании BeanPostProcessor и BeanFactoryPostProcessorSpring创建的扩展点
, пользователи могут создавать свои собственные классы реализации для модификации Bean или BeanFactory.
Обратите внимание, что для ApplicationContext контейнер может自动检测并加载
BeanPostProcessor и BeanFactoryPostProcessor, но BeanFactory не работает, нужно вызывать метод самостоятельно手动注册
. Может быть несколько BeanPostProcessors и BeanFactoryPostProcessors.
ApplicationContext также может быть основан на org.springframework.core.PriorityOrdered и org.springframework.core.Ordered.自定义排序
, но BeanFactory не может, порядок по умолчанию注册顺序
.
Здесь мне нужно прояснить следующие два сбивающих с толку слова:
-
Instantiation
: создание экземпляра, относится к вызову构造函数
создавать экземпляр -
Initialization
:Инициализация, которая относится к циклу объявления Бинаinit-method
указанный метод илиInitializingBean.afterPropertiesSet()
метод
Ниже мы опишем эти часто используемые интерфейсы:
Общее описание интерфейса
BeanNameAware
Этот интерфейс имеет только один метод setBeanName(String name), который используется для полученияid或者name
BeanFactoryAware
Этот интерфейс имеет только один метод setBeanFactory(BeanFactory beanFactory), который используется для получения当前环境中的BeanFactory
-
ApplicationContextAware
Этот интерфейс имеет только один метод setApplicationContext(ApplicationContext applicationContext), который используется для получения当前环境中的ApplicationContext
После получения контейнера IOC вы можете изменять bean-компоненты и другие операции.
InitializingBean
Интерфейс имеет только один метод afterPropertiesSet(), который вызывается после завершения внедрения свойства.DisposableBean
Этот интерфейс имеет только один метод destroy(), который вызывается при уничтожении контейнера и до указанного пользователем метода destroy.BeanPostProcessor
Этот интерфейс имеет два метода:
- postProcessBeforeInitialization (объектный компонент, String beanName): в
初始化之前
вызовите этот метод - postProcessAfterInitialization (объектный компонент, String beanName): в
初始化之后
вызовите этот метод
Благодаря сигнатуре метода мы можем знать, что можем отфильтровать bean-компоненты, которые нам нужно настроить по beanName.
- InstantiationAwareBeanPostProcessor
Этот класс является подинтерфейсом BeanPostProcessor, и обычно используются следующие три метода.
- postProcessBeforeInstantiation (Class beanClass, String beanName): в bean-компоненте
实例化之前
перечислить - postProcessProperties (PropertyValues pvs, Object bean, String beanName): в bean-компоненте
实例化之后、设置属性前
перечислить - postProcessAfterInstantiation (Class beanClass, String beanName): в Bean
实例化之后
перечислить
Жизненный цикл тестового компонента
Давайте напишем пример для проверки жизненного цикла Bean, о котором мы упоминали выше.
Сначала мы создаем нового пользователя, который реализует наши интерфейсы BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean.
Затем мы реализуем собственный BeanPostProcessor.
Реализуйте свой собственный InstantiationAwareBeanPostProcessor
Файл конфигурации xml выглядит следующим образом
<context:component-scan base-package="com.xiaohuan.springtest"/>
<bean id="user" class="com.xiaohuan.springtest.beanlifecycle.User" init-method="myInit" destroy-method="myDestroy">
<!-- 构造函数注入 -->
<constructor-arg index="0" type="int">
<value>1</value>
</constructor-arg>
<constructor-arg index="1" type="java.lang.String">
<value>xiaohuan</value>
</constructor-arg>
<!-- setter方法注入 -->
<property name="id" value="2"/>
<property name="name" value="dahuan"/>
</bean>
Напишем собственный тестовый класс
Наконец запустите проект