Публичный аккаунт WeChat:студия gmapper Колонка самородков:glmapper Вейбо:Сумасшедший Stone_henu Добро пожаловать, чтобы обратить внимание, учиться и делиться технологиями вместе
в этой статьеПоговорим о механизме расширения в Spring (1)средняя параSpringАнализируется механизм события. тогда дляSpringBootНапример, это вSpringКакие расширения были сделаны на его основе? Поговорим об этом в будущемSpringBootсобытия в .
В процессе запуска SpringBoot некоторые классы из spring.factories будут загружаться через механизм SPI, включая классы, связанные с событиями.
SpringApplicationRunListener
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
SpringApplicationRunListenerклассSpringBootновый класс в .SpringApplicationиспользуйте их в классе для косвенного вызоваApplicationListener. Еще один новый классSpringApplicationRunListeners,SpringApplicationRunListenersсодержит несколькоSpringApplicationRunListener.
SpringApplicationRunListener
SpringApplicationRunListenerинтерфейс указываетSpringBootжизненного цикла, транслировать соответствующее событие в каждом жизненном цикле, вызывать фактическиеApplicationListenerсвоего рода. через паруSpringApplicationRunListenerанализа, также возможноSpringBootПонимание всего процесса запуска было бы большим подспорьем.
упомянутый выше,SpringApplicationRunListenersдаSpringApplicationRunListenerколлекция, включающая множествоSpringApplicationRunListenerпример;SpringApplicationКласс фактически используетSpringApplicationRunListenersкласс, сSpringApplicationRunListenerЖизненный цикл тот же, называяSpringApplicationRunListener. Затем транслируйте соответствующее событие наApplicationListener.
EventPublishingRunListenerклассSpringApplicationRunListenerКласс реализации интерфейса, который имеет функцию трансляции событий. его внутреннее использованиеApplicationEventMulticasterСобытие публикуется до фактического обновления контекста. Посмотрите нижеEventPublishingRunListenerСобытия, соответствующие жизненному циклу класса.
ApplicationStartingEvent
ApplicationStartingEventдаSpringBootСобытие, которое выполняется при запуске автозагрузки, что можно получить в этом событииSpringApplicationобъект, вы можете сделать некоторые настройки перед выполнением, соответствующий метод вызоваstarting().
ApplicationEnvironmentPreparedEvent
ApplicationEnvironmentPreparedEventдаSpringBootсоответствоватьEnviromentСобытие, которое выполняется, когда оно готово, контекст в это времяcontextЕще не создан. получено в этом монитореConfigurableEnvironmentПосле этого вы можете выполнять операции с информацией о конфигурации, такие как изменение информации о конфигурации по умолчанию, добавление дополнительной информации о конфигурации и т. д. Соответствующий метод жизненного циклаenvironmentPrepared(environment);SpringCloud, в этот момент инициализируется контекст загрузки.
ApplicationContextInitializedEvent
когдаSpringApplicationи готовApplicationContext, а при загрузке любогоbeanвызывается перед определениемApplicationContextInitializersопубликованы события. Соответствующий метод жизненного циклаcontextPrepared()
ApplicationPreparedEvent
ApplicationPreparedEventдаSpringBootконтекстcontextСоздание завершено — это публикуемое событие, но на этот разspringсерединаbeanЕще не полностью загружен. Здесь контекст может быть передан для выполнения некоторых дополнительных операций. Но в этом слушателе нет возможности получить кастомныйbeanи работать. Соответствующий метод жизненного циклаcontextLoaded().
ApplicationStartedEvent
Это событие было введено в версии 2.0; конкретный выпуск заключается в том, что после обновления контекста приложения любой вызовApplicationRunnerиCommandLineRunnerперед запуском программы.
ApplicationReadyEvent
это иApplicationStartedEventОчень похоже, он также вызывается после обновления контекста приложения, разница в том, что в это времяApplicationRunnerиCommandLineRunnerзавершил вызов, что также означает, чтоSpringBootЗагрузка завершена.
ApplicationFailedEvent
SpringBootКогда событие выполняется при запуске исключения, когда возникает исключение, лучше всего добавить обработчик, соответствующий виртуальной машине, для повторного использования и высвобождения ресурсов, чтобы информация об исключении могла быть обработана мирным путем.
демо и порядок выполнения каждого события
Распечатаны демо, соответствующие следующим событиям, и порядок выполнения.
GlmapperApplicationStartingEventListener
public class GlmapperApplicationStartingEventListener implements ApplicationListener<ApplicationStartingEvent> {
@Override
public void onApplicationEvent(ApplicationStartingEvent applicationStartingEvent) {
System.out.println("execute ApplicationStartingEvent ...");
}
}
GlmapperApplicationEnvironmentPreparedEvent
public class GlmapperApplicationEnvironmentPreparedEvent implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) {
System.out.println("execute ApplicationEnvironmentPreparedEvent ...");
}
}
GlmapperApplicationContextInitializedEvent
public class GlmapperApplicationContextInitializedEvent implements ApplicationListener<ApplicationContextInitializedEvent> {
@Override
public void onApplicationEvent(ApplicationContextInitializedEvent applicationContextInitializedEvent) {
System.out.println("execute applicationContextInitializedEvent ...");
}
}
GlmapperApplicationPreparedEvent
public class GlmapperApplicationPreparedEvent implements ApplicationListener<ApplicationPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationPreparedEvent applicationPreparedEvent) {
System.out.println("execute ApplicationPreparedEvent ...");
}
}
GlmapperApplicationStartedEvent
public class GlmapperApplicationStartedEvent implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {
System.out.println("execute ApplicationStartedEvent ...");
}
}
GlmapperApplicationReadyEvent
public class GlmapperApplicationReadyEvent implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
System.out.println("execute ApplicationReadyEvent ...");
}
}
Результаты
Архитектура событий в SpringBoot
здесьSpringApplicationRunListenerДля этого класса. в классе реализацииEventPublishingRunListener, существует два режима публикации событий:
пройти черезSimpleApplicationEventMulticasterтранслировать событие
Все слушатели передаются в соответствующиеContext
такEventPublishingRunListenerНе только ответственность за публикацию событий, но и в нужное времяSpringApplicationПолученный слушатель связан с контекстом приложения.
SimpleApplicationEventMulticaster
SimpleApplicationEventMulticasterдаSpringТранслятор событий по умолчанию. Давайте посмотрим, как это работает:
Как вы можете видеть из приведенного выше фрагмента кода, он вызывает каждого слушателя, проходя через каждый зарегистрированный слушатель и запускаяonApplicationEventметод.
здесьAbstractApplicationContextДавайте поговорим об этом, этот класс фактически отвечает за инициализацию системы событий.
Инициализация системы событий
Инициализация системы событий соответствуетSpringBootпроцесс запускаrefreshContextСюда;refreshContextВ частности, вызовите метод AbstractApplicationContext.refresh() и, наконец, вызовите initApplicationEventMulticaster(), чтобы завершить инициализацию системы событий. Код выглядит следующим образом:
Пользователи могут определить собственный вещатель событий для контейнера, если реализацияApplicationEventMulticasterВот и все,SpringОн будет зарегистрирован как распространитель событий контейнера через механизм отражения.Если настроенный внешний распространитель событий не найден,Springиспользуется по умолчаниюSimpleApplicationEventMulticasterкак ведущий событий.
регистрация на мероприятие
Регистрация событий выполняется после завершения инициализации системы событий, а такжеAbstractApplicationContext.refresh()вызывается метод.
Здесь делаются три вещи:
Сначала зарегистрируйте статически указанныйlisteners; сюда входят те прослушиватели, которые мы настроили.
перечислитьDefaultListableBeanFactoryсерединаgetBeanNamesForTypeполучить обычайApplicationListenerbeanЗарегистрируйтесь на мероприятия.
Трансляция ранних событий.
трансляция события
Релиз мероприятия сопровождаетсяSpringBootВесь жизненный цикл стартапа. Разные этапы соответствуют публикации разных событий. Мы проанализировали каждое событие выше. Давайте посмотрим на реализацию публикации событий:
Событие в EarlyApplicationEvents предназначено для сохранения информации об уведомлении, когда вещатель не установлен.Как только контейнер будет установлен, он будет уведомлен непосредственно в будущем.
Широковещательное событие в конечном итоге вызываетсяApplicationEventMulticasterизmulticastEventреализовать. иmulticastEventТо есть способ исполнения события.
выполнение события
вышеSimpleApplicationEventMulticasterРаздел уже представленmulticastEventСюда. добавь если естьtaskExecutorбудет использовать параллельный режим для выполнения событий, но на самом делеSimpleApplicationEventMulticasterРеализации пула потоков не предусмотрено.По умолчанию события выполняются синхронно (org.springframework.core.task.SyncTaskExecutor), поэтому, если вам нужна асинхронная конфигурация, вам нужно реализовать пул потоков самостоятельно.
Фаза события в процессе запуска SpringBoot
вернуться сюдаSpringApplicationизrunметод см.SpringBootЧто делает каждая фаза события во время запуска.
starting -> ApplicationStartingEvent
здесьdebugприбытьstartingметод, восходящий кmulticastEvent,здесьtypeзаApplicationStartingEvent; соответствующие события таковы:
LoggerApplicationListener: настроить систему ведения журнала. использоватьlogging.configКонфигурация, указанная переменной среды, или конфигурация по умолчанию
BackgroundPreinitializer: запуск некоторых трудоемких задач инициализации как можно раньше с использованием фонового потока.
DelegatingApplicationListener: перенаправить в переменные среды после прослушивания событийcontext.listener.classesуказанные прослушиватели событий
LiquibaseServiceLocatorApplicationListener: используйтеSpringBootисполняемыйjarПакеты работают с заменой версийliquibase ServiceLocator
ConfigFileApplicationListener:EnvironmentPostProcessor, читать файлы конфигурации из общепринятых мест, например из следующих каталоговapplication.properties,application.ymlи другие файлы конфигурации:
classpath:
file:.
classpath:config
file:./config/
Его также можно настроить для чтения файлов конфигурации из других указанных мест.
ClasspathLoggingApplicationListener: событие готово для средыApplicationEnvironmentPreparedEvent/применить не удается件ApplicationFailedEventответить на журналDEBUGвыходной уровеньTCCL(thread context class loader)изclasspath.
FileEncodingApplicationListener: прекращает запуск приложения, если кодировка системного файла отличается от указанной в переменной среды. Конкретный метод заключается в сравнении свойств системыfile.encodingи переменные окруженияspring.mandatory-file-encodingОни равны (без учета регистра).
ConditionEvaluationReportLoggingListener: на самом деле реализованоApplicationContextInitializerинтерфейс, целью которого являетсяConditionEvaluationReportДля записи в журнал используйтеDEBUGвыход уровня. Отчет о сбое программы вызывает вывод сообщения, в котором пользователю предлагается отобразить отчет в режиме отладки. Это связано сConditionEvaluationReportListenerпрослушиватель событий, а затем вывод, когда происходит соответствующее событиеConditionEvaluationReportОтчет.
ClearCachesApplicationListener: после загрузки контекста приложения очистить кеш и реагировать на события.ContextRefreshedEvent.
Эти два проходят через весь процесс, и здесь они объясняются отдельно:
BackgroundPreinitializer: для некоторых трудоемких задач используйте фоновый поток, чтобы запустить их как можно раньше, чтобы начать выполнение инициализации, чтоSpringBootповедение по умолчанию. Эти действия по инициализации также можно назвать предварительной инициализацией. Вы можете установить свойства системы,spring.backgroundpreinitializer.ignoreзаtrueЭтот механизм можно отключить. Когда этот механизм отключен, соответствующие задачи инициализации выполняются в потоке переднего плана.
DelegatingApplicationListener: прослушивает события приложения и передает эти события приложения свойствам среды.context.listener.classesуказанные слушатели.
резюме
Уже,SpringBootМатериалы, связанные с событием, закончились. Эта статья изSpringApplicationRunListenerНачнем с этого класса, а затем представимSpringBootСобытие, запустившее процесс, и жизненный цикл события. Наконец представилSpringBootЭти встроенные прослушиватели соответствуют различным этапам процесса запуска.
В начале нового года поздравляю всех с Новым годом!