Адрес Github китайского аннотационного проекта SpringBoot:
GitHub.com/Примечания к источнику/…
Эта статья продолжаетАнализ исходного кода механизма мониторинга событий SpringBoot (1) Исходный код SpringBoot (9)
1 Уроки прошлого
Ознакомившись со старым и узнав новое, давайте кратко повторим содержание предыдущей статьи.В предыдущей статье мы разобралиПринцип трансляции событий жизненного цикла при запуске SpringBoot, ключевые шаги теперь сжаты и обобщены:
- Подготовьтесь к трансляции встроенных событий жизненного цикла SpringBoot: 1) Сначала загрузите
ApplicationListener
Класс реализации слушателя; 2) Затем загрузите класс расширения SPIEventPublishingRunListener
. - Использовать при запуске SpringBoot
EventPublishingRunListener
транслировать события жизненного цикла, затемApplicationListener
Класс реализации прослушивателя прослушивает соответствующие события жизненного цикла, чтобы выполнить некоторую логическую работу по инициализации.
2 Введение
Предметом прошлой статьи был анализ принципа трансляции событий жизненного цикла при старте SpringBoot, в этой статье мы подробно разберем исходный код семи встроенных событий жизненного цикла в Spring Boot.
3 Анализ исходного кода события жизненного цикла SpringBoot
Чтобы проанализировать события жизненного цикла SpringBoot, давайте сначала посмотрим на диаграмму структуры классов:На приведенном выше рисунке вы можете увидеть взаимосвязь между классами событий:
- Родительский класс верхнего уровня является базовым классом событий JDK.
EventObject
; - Затем базовый класс событий Spring
ApplicationEvent
Унаследовал базовый класс событий JDK.EventObject
; - Во-вторых, базовый класс событий жизненного цикла SpringBoot
SpringApplicationEvent
Унаследовано от базового класса событий Spring.ApplicationEvent
; - Наконец, 7 конкретных классов событий жизненного цикла SpringBoot наследуют базовый класс событий жизненного цикла SpringBoot.
SpringApplicationEvent
.
3.1 Базовый класс событий JDK EventObject
EventObject
Класс является базовым классом событий JDK, который, можно сказать, является основой всех классов событий Java, то есть все классы событий Java прямо или косвенно наследуются от этого класса.Исходный код выглядит следующим образом:
// EventObject.java
public class EventObject implements java.io.Serializable {
private static final long serialVersionUID = 5516075349620653480L;
/**
* The object on which the Event initially occurred.
*/
protected transient Object source;
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @exception IllegalArgumentException if source is null.
*/
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
/**
* The object on which the Event initially occurred.
*
* @return The object on which the Event initially occurred.
*/
public Object getSource() {
return source;
}
/**
* Returns a String representation of this EventObject.
*
* @return A a String representation of this EventObject.
*/
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
можно увидетьEventObject
класс имеет только одно свойствоsource
, это свойство используется для записи того, в каком классе произошло начальное событие, например, оно будет сгенерировано во время процесса запуска SpringBoot.ApplicationStartingEvent
событие, которое изначально было вSpringApplication
испущенный класс, поэтомуsource
то естьSpringApplication
объект.
3.2 Базовый класс событий Spring ApplicationEvent
ApplicationEvent
Унаследовал базовый класс события DKEventObject
class является базовым классом событий Spring, унаследованным всеми специфическими классами событий Spring, исходный код выглядит следующим образом:
// ApplicationEvent.java
/**
* Class to be extended by all application events. Abstract as it
* doesn't make sense for generic events to be published directly.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public abstract class ApplicationEvent extends EventObject {
/** use serialVersionUID from Spring 1.2 for interoperability. */
private static final long serialVersionUID = 7099057708183571937L;
/** System time when the event happened. */
private final long timestamp;
/**
* Create a new ApplicationEvent.
* @param source the object on which the event initially occurred (never {@code null})
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
/**
* Return the system time in milliseconds when the event happened.
*/
public final long getTimestamp() {
return this.timestamp;
}
}
можно увидетьApplicationEvent
имеет одно и только одно свойствоtimestamp
, который используется для записи времени, когда произошло событие.
3.3 Базовый класс событий SpringBoot SpringApplicationEvent
SpringApplicationEvent
Класс наследует базовый класс событий Spring.ApplicationEvent
, является родительским классом всех встроенных событий жизненного цикла SpringBoot, исходный код выглядит следующим образом:
/**
* Base class for {@link ApplicationEvent} related to a {@link SpringApplication}.
*
* @author Phillip Webb
*/
@SuppressWarnings("serial")
public abstract class SpringApplicationEvent extends ApplicationEvent {
private final String[] args;
public SpringApplicationEvent(SpringApplication application, String[] args) {
super(application);
this.args = args;
}
public SpringApplication getSpringApplication() {
return (SpringApplication) getSource();
}
public final String[] getArgs() {
return this.args;
}
}
можно увидетьSpringApplicationEvent
имеет одно и только одно свойствоargs
, это свойство является параметром командной строки при запуске SpringBoot, то есть меткой@SpringBootApplication
в стартовом классеmain
параметры функции.
3.4 Класс событий жизненного цикла SpringBoot
Далее давайте посмотримSpringBoot
Встроенные события жизненного циклаSpringApplicationEvent
конкретные подклассы .
3.4.1 ApplicationStartingEvent
// ApplicationStartingEvent.java
public class ApplicationStartingEvent extends SpringApplicationEvent {
public ApplicationStartingEvent(SpringApplication application, String[] args) {
super(application, args);
}
}
Опубликовано при запуске SpringBootApplicationStartingEvent
События, время которых публикуется до создания переменной окружения Environment или контейнера ApplicationContext, но после регистрацииApplicationListener
После конкретного слушателя флаг флагSpringApplication
Начать загрузку.
3.4.2 ApplicationEnvironmentPreparedEvent
// ApplicationEnvironmentPreparedEvent.java
public class ApplicationEnvironmentPreparedEvent extends SpringApplicationEvent {
private final ConfigurableEnvironment environment;
/**
* Create a new {@link ApplicationEnvironmentPreparedEvent} instance.
* @param application the current application
* @param args the arguments the application is running with
* @param environment the environment that was just created
*/
public ApplicationEnvironmentPreparedEvent(SpringApplication application,
String[] args, ConfigurableEnvironment environment) {
super(application, args);
this.environment = environment;
}
/**
* Return the environment.
* @return the environment
*/
public ConfigurableEnvironment getEnvironment() {
return this.environment;
}
}
можно увидетьApplicationEnvironmentPreparedEvent
еще одно событиеenvironment
Атрибуты, мы могли бы подумать об этом, большеenvironment
Какова роль атрибутов?
ответApplicationEnvironmentPreparedEvent
событиеenvironment
Функция атрибута заключается в использовании механизма публикации и подписки на события, и соответствующие прослушиватели могутApplicationEnvironmentPreparedEvent
Снято с мероприятияenvironment
переменная, то мы можем написатьenvironment
Атрибут для добавления значения атрибута или чтенияenvironment
значение в переменной.
Возьмите каштан:
ConfigFileApplicationListener
Слушатель слушаетApplicationEnvironmentPreparedEvent
событие, затем выньтеApplicationEnvironmentPreparedEvent
событиеenvironment
имущества, а затем дляenvironment
увеличение атрибутаapplication.properties
Значения переменных среды в конфигурационных файлах.
Когда SpringApplication запущен и переменная средыEnvironment
После того, как он был создан и является переменной средыEnvironment
Настроил командную строку иServlet
и другие типы переменных окружения, они будут выпущены в это время.ApplicationEnvironmentPreparedEvent
мероприятие.
мониторApplicationEnvironmentPreparedEvent
Первым прослушивателем события являетсяConfigFileApplicationListener
,потому чтоConfigFileApplicationListener
Слушатель также должен быть переменной среды.Environment
Увеличиватьapplication.properties
Переменные окружения в конфигурационном файле, после этого некоторые тоже прослушиваютсяApplicationEnvironmentPreparedEvent
Когда другие слушатели события слушают это событие, вы можете произнести переменную среды в это времяEnvironment
Почти готов.
считать:Слушатели, прослушивающие одно и то же событие, выполняют логику прослушивания по порядку. Мы можем подумать о том, когда эта логика сортировки отсортирована? А почему так отсортировано?
3.4.3 ApplicationContextInitializedEvent
// ApplicationContextInitializedEvent.java
public class ApplicationContextInitializedEvent extends SpringApplicationEvent {
private final ConfigurableApplicationContext context;
/**
* Create a new {@link ApplicationContextInitializedEvent} instance.
* @param application the current application
* @param args the arguments the application is running with
* @param context the context that has been initialized
*/
public ApplicationContextInitializedEvent(SpringApplication application,
String[] args, ConfigurableApplicationContext context) {
super(application, args);
this.context = context;
}
/**
* Return the application context.
* @return the context
*/
public ConfigurableApplicationContext getApplicationContext() {
return this.context;
}
}
можно увидетьApplicationContextInitializedEvent
больше событийConfigurableApplicationContext
Типcontext
Атрибуты,context
Функция атрибута также заключается в том, чтобы соответствующий слушатель мог получить этоcontext
Свойство выполняет некоторую логику, конкретная роль будет в3.4.4
деталь.
ApplicationContextInitializedEvent
событие вApplicationContext
После создания контейнера иApplicationContext
контейнер установленenvironment
переменная и выполняетсяApplicationContextInitializers
Запускается после метода инициализации определения bean-компонента, но до загрузки определения bean-компонента, указывая на то, что ApplicationContext был инициализирован.
Расширение:можно увидеть
ApplicationContextInitializedEvent
это дляcontext
конфигурация контейнераenvironment
Запускается после переменной, в это времяApplicationContextInitializedEvent
Ждите события, пока естьcontext
контейнер, затем другие потребностиenvironment
Слушатели для переменных среды должны начинаться только сcontext
выигратьenvironment
переменная, поэтомуApplicationContextInitializedEvent
Нет необходимости настраивать событиеenvironment
Атрибуты.
3.4.4 ApplicationPreparedEvent
// ApplicationPreparedEvent.java
public class ApplicationPreparedEvent extends SpringApplicationEvent {
private final ConfigurableApplicationContext context;
/**
* Create a new {@link ApplicationPreparedEvent} instance.
* @param application the current application
* @param args the arguments the application is running with
* @param context the ApplicationContext about to be refreshed
*/
public ApplicationPreparedEvent(SpringApplication application, String[] args,
ConfigurableApplicationContext context) {
super(application, args);
this.context = context;
}
/**
* Return the application context.
* @return the context
*/
public ConfigurableApplicationContext getApplicationContext() {
return this.context;
}
}
Вы также можете увидетьApplicationPreparedEvent
больше событийConfigurableApplicationContext
Типcontext
недвижимость, большеcontext
Функция атрибута состоит в том, чтобы позволить слушателям, прослушивающим событие, получитьcontext
свойство, слушатель получаетcontext
Обычно атрибуты выполняют следующие функции:
- уйти с мероприятия
context
свойства, а затем вы можете добавить некоторые постпроцессоры, такие какConfigFileApplicationListener
Слушатель слушаетApplicationPreparedEvent
После события выньтеcontext
переменная, черезcontext
добавлена переменнаяPropertySourceOrderingPostProcessor
этот постпроцессор; - пройти через
context
извлечение атрибутовbeanFactory
контейнер, затем зарегистрируйте некоторыеbean
,НапримерLoggingApplicationListener
слушатель черезApplicationPreparedEvent
событиеcontext
извлечение атрибутовbeanFactory
контейнер, затем зарегистрированныйspringBootLoggingSystem
этот синглтонbean
; - пройти через
context
извлечение атрибутовEnvironment
переменные среды, а затем вы можете манипулировать переменными среды, такими какPropertiesMigrationListener
.
ApplicationPreparedEvent
событие вApplicationContext
Запускается, когда контейнер полностью готов, но до его обновления, на данном этапеbean
Определение было загружено и все ещеenvironment
Он готов к использованию.
3.4.5 ApplicationStartedEvent
// ApplicationStartedEvent.java
public class ApplicationStartedEvent extends SpringApplicationEvent {
private final ConfigurableApplicationContext context;
/**
* Create a new {@link ApplicationStartedEvent} instance.
* @param application the current application
* @param args the arguments the application is running with
* @param context the context that was being created
*/
public ApplicationStartedEvent(SpringApplication application, String[] args,
ConfigurableApplicationContext context) {
super(application, args);
this.context = context;
}
/**
* Return the application context.
* @return the context
*/
public ConfigurableApplicationContext getApplicationContext() {
return this.context;
}
}
ApplicationStartedEvent
Событие будет обновлено после контейнера, ноApplicationRunner
а такжеCommandLineRunner
изrun
Срабатывает перед выполнением метода, флагSpring
Контейнер был обновлен, и на данный момент контейнер готов.
Расширение:упоминается здесь
ApplicationRunner
а такжеCommandLineRunner
Что делает интерфейс? Обычно мы будем вSpring
После обновления контейнера могут быть некоторые статические данные, такие как системные параметры, которые необходимо загрузить в это время, и мы можем реализовать их в это время.ApplicationRunner
илиCommandLineRunner
интерфейс для реализации загрузки статических данных.
3.4.6 ApplicationReadyEvent
// ApplicationReadyEvent.java
public class ApplicationReadyEvent extends SpringApplicationEvent {
private final ConfigurableApplicationContext context;
/**
* Create a new {@link ApplicationReadyEvent} instance.
* @param application the current application
* @param args the arguments the application is running with
* @param context the context that was being created
*/
public ApplicationReadyEvent(SpringApplication application, String[] args,
ConfigurableApplicationContext context) {
super(application, args);
this.context = context;
}
/**
* Return the application context.
* @return the context
*/
public ConfigurableApplicationContext getApplicationContext() {
return this.context;
}
}
ApplicationReadyEvent
Мероприятие называетсяApplicationRunner
а такжеCommandLineRunner
изrun
Запускается после метода, на этот раз флагSpringApplication
уже бежит.
3.4.7 ApplicationFailedEvent
// ApplicationFailedEvent.java
public class ApplicationFailedEvent extends SpringApplicationEvent {
private final ConfigurableApplicationContext context;
private final Throwable exception;
/**
* Create a new {@link ApplicationFailedEvent} instance.
* @param application the current application
* @param args the arguments the application was running with
* @param context the context that was being created (maybe null)
* @param exception the exception that caused the error
*/
public ApplicationFailedEvent(SpringApplication application, String[] args,
ConfigurableApplicationContext context, Throwable exception) {
super(application, args);
this.context = context;
this.exception = exception;
}
/**
* Return the application context.
* @return the context
*/
public ConfigurableApplicationContext getApplicationContext() {
return this.context;
}
/**
* Return the exception that caused the failure.
* @return the exception
*/
public Throwable getException() {
return this.exception;
}
}
можно увидетьApplicationFailedEvent
В дополнение к еще одному событиюcontext
Помимо атрибутов есть еще одинThrowable
Типexception
Свойство используется для записи исключений, когда SpringBoot не запускается.
ApplicationFailedEvent
Событие запускается, когда SpringBoot не удается запустить, указывая на то, что SpringBoot не удалось запустить.
4 Резюме
Эта статья относительно проста и содержит подробный анализ семи событий жизненного цикла, встроенных в SpringBoot. Давайте рассмотрим эти события жизненного цикла и их использование на картинке из предыдущей статьи:
5 в конце
Поскольку некоторые друзья предположили, что некоторые статьи по анализу исходного кода были слишком длинными, что приводило к недостатку терпения и удобочитаемости, поэтому, если статьи по анализу исходного кода в будущем будут слишком длинными, автор рассмотрит возможность их разделения на несколько статей, что быть короче и короче. Теперь это легче читать, хе-хе.
[Примечания к источнику] Адрес Github: