SpringBoot 启动源码 -初了解
所以我就是想知道springBoot到底是如何启动的,它都做了些啥。
那就一步一步走过去看看。
1.根据传入的主类,创建SpringApplication类(进行一些初始化)
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE; //benner 的模式
this.logStartupInfo = true; // 记录启动信息日志
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true; //配置headless模式
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//读取jar包的配置文件
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
在setInitializers
和 setListeners
的时候,使用的getSpringFactoriesInstances
,通过的读取jar包的配置文件并加载对应的实例。
1.1 读取所有的jar包的META-INF/spring.factories
配置文件
读取配置文件内容将配置文件的所有配置读取入catch中
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return this.getSpringFactoriesInstances(type, new Class[0]);
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = this.getClassLoader();
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));//这里获取类的名字
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
//根据传入的类加载器,如果cache内没有缓存的数据就去读取对应的jar包的META_INF/spring.factories 的这个配置文件。按键值对读取配置文件并放入缓存
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var10 = var9.length;
for(int var11 = 0; var11 < var10; ++var11) {
String factoryImplementationName = var9[var11];
result.add(factoryTypeName, factoryImplementationName.trim());
}
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
配置例如:
spring-beans-5.2.4.RELEASE.jar
org.springframework.beans.BeanInfoFactory=org.springframework.beans.ExtendedBeanInfoFactory
2.执行SpringApplication的run方法(逐行理解)
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch(); //执行计时器
stopWatch.start(); //计时开始 测试见2.1
ConfigurableApplicationContext context = null; //初始化
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); //初始化
this.configureHeadlessProperty(); //读取系统参数是否配置为headless模式 (见2.2)
SpringApplicationRunListeners listeners = this.getRunListeners(args); //根据传入的参数获取监听器实例 见(2.3)
listeners.starting();//监听器启动(见2.4)
Collection exceptionReporters; //初始化
try {
//将定义的args 参数 初始化为ApplicationArguments对象
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//根据传入的监听器和参数,配置环境 见2.5
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
//读取配置文件中的spring.beaninfo.ignore
this.configureIgnoreBeanInfo(environment);
// benner图输出
Banner printedBanner = this.printBanner(environment);
// 根据应用类型的不同,创建不同的应用上下文 见2.6
context = this.createApplicationContext();
//获取SpringBootExceptionReporter实例
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
//Context 处理 见2.7 将类都加载了
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 将context进行refresh
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
//计时结束
stopWatch.stop();
//打印日志
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
//监听器到started状态
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
// 监听器到running状态
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
2.1 StopWatch 计时器的相关使用示例
public class TestStopWatch {
public static Logger logger = LoggerFactory.getLogger(TestStopWatch.class);
public static void main(String[] args) throws InterruptedException {
StopWatch stopWatch = new StopWatch("Watch1");
// 计时任务开始:只能启动一个
stopWatch.start("task1");
Thread.sleep(100);
stopWatch.stop();
stopWatch.start("task2");
Thread.sleep(100);
stopWatch.stop();
logger.info("{}", stopWatch.prettyPrint());
}
}
14:32:07.192 [main] INFO TestStopWatch - StopWatch ‘Watch1’: running time = 207718700 ns
ns % Task name
102259100 049% task1
105459600 051% task2
2.2 配置系统为headless模式
private void configureHeadlessProperty() {
System.setProperty("java.awt.headless", System.getProperty("java.awt.headless", Boolean.toString(this.headless)));
}
2.2.1 headless模式
Headless模式是在系统缺少外部设备,如鼠标、键盘、显示器等的时候的配置模式。
适用于什么地方?假设您的应用程序重复生成某个图像,例如,每次用户登录系统时都必须更改的图形码。创建图像时,您的应用程序既不需要显示器也不需要键盘。现在让我们假设您的项目中有一台没有显示设备、键盘或鼠标的大型机或专用服务器。理想的决定是使用该环境的强大计算能力来处理视觉和非视觉特征。然后可以将在无头模式系统中生成的图像传递给有头系统以进行进一步渲染。
官网解释:传送
2.3 获取监听器实例
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class[]{SpringApplication.class, String[].class};
//调用构造器
return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
// 根据传入的类型,返回相关实例列表
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return this.getSpringFactoriesInstances(type, new Class[0]);
}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = this.getClassLoader();
//根据传入的类型名称,查找jar包的相关配置,加载所有的SpringApplicationRunListener
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
SpringApplicationRunListeners 的构造器
class SpringApplicationRunListeners {
private final Log log;
private final List<SpringApplicationRunListener> listeners;
SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
this.log = log;
this.listeners = new ArrayList(listeners);
}
}
2.4 监听器启动
class SpringApplicationRunListeners {
private final Log log;
private final List<SpringApplicationRunListener> listeners;
void starting() {
Iterator var1 = this.listeners.iterator();
//遍历启动每一个监听器
while(var1.hasNext()) {
SpringApplicationRunListener listener = (SpringApplicationRunListener)var1.next();
listener.starting();
}
}
}
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
private final SpringApplication application;
private final String[] args;
private final SimpleApplicationEventMulticaster initialMulticaster;
// 初始化
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
this.initialMulticaster = new SimpleApplicationEventMulticaster();
Iterator var3 = application.getListeners().iterator();
while(var3.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var3.next();
this.initialMulticaster.addApplicationListener(listener);
}
}
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
}
EventPublishingRunListener 通过 调用initialMulticaster.multicastEvent
监听应用starting
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Nullable
private Executor taskExecutor;
@Nullable
private ErrorHandler errorHandler;
public SimpleApplicationEventMulticaster() {
}
public void multicastEvent(ApplicationEvent event) {
this.multicastEvent(event, this.resolveDefaultEventType(event));
}
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
// 获取事件类型,如果传入的是Null 就取默认的
ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
// 获取执行器
Executor executor = this.getTaskExecutor();
Iterator var5 = this.getApplicationListeners(event, type).iterator();
//遍历监听器执行
while(var5.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var5.next();
if (executor != null) {
executor.execute(() -> {
this.invokeListener(listener, event);
});
} else {
this.invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
// 获取定义的错误处理器,即执行出错的时候的运行逻辑
ErrorHandler errorHandler = this.getErrorHandler();
if (errorHandler != null) {
try {
this.doInvokeListener(listener, event);
} catch (Throwable var5) {
errorHandler.handleError(var5);
}
} else {
this.doInvokeListener(listener, event);
}
}
//实际执行处是执行监听器类的onApplicationEvent方法
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
} catch (ClassCastException var6) {
String msg = var6.getMessage();
if (msg != null && !this.matchesClassCastMessage(msg, event.getClass())) {
throw var6;
}
Log logger = LogFactory.getLog(this.getClass());
if (logger.isTraceEnabled()) {
logger.trace("Non-matching event type for listener: " + listener, var6);
}
}
}
}
2.5 环境预准备
根据传入的监听器和参数,进行环境预准备
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
ConfigurableEnvironment environment = this.getOrCreateEnvironment();
// 将预先准备的环境设置到this.configureEnvironment中
this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach((Environment)environment);
listeners.environmentPrepared((ConfigurableEnvironment)environment);
this.bindToSpringApplication((ConfigurableEnvironment)environment);
if (!this.isCustomEnvironment) {
environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
}
ConfigurationPropertySources.attach((Environment)environment);
return (ConfigurableEnvironment)environment;
}
//获取或者根据web应用类型创建一个环境
private ConfigurableEnvironment getOrCreateEnvironment() {
if (this.environment != null) {
return this.environment;
} else {
// webApplicationType 是在初始化SpringApplication类的时候通过
// WebApplicationType.deduceFromClasspath() 来确定的 见2.5.1
switch(this.webApplicationType) {
case SERVLET: // 基于web的应用
return new StandardServletEnvironment();
case REACTIVE: //反应式web应用
return new StandardReactiveWebEnvironment();
default: //标准
return new StandardEnvironment();
}
}
}
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
//该值在初始化时设置了
if (this.addConversionService) {
// 单例模式获取ConversionService 见2.5.2
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
//给环境设置转换服务实例
environment.setConversionService((ConfigurableConversionService)conversionService);
}
//设置property源
this.configurePropertySources(environment, args);
// 配置Profile
this.configureProfiles(environment, args);
}
// 将命令行输入的参数 转换为SimpleCommandLinePropertySource类
protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
MutablePropertySources sources = environment.getPropertySources();
if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
}
if (this.addCommandLineProperties && args.length > 0) {
String name = "commandLineArgs";
if (sources.contains(name)) {
PropertySource<?> source = sources.get(name);
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
composite.addPropertySource(source);
sources.replace(name, composite);
} else {
sources.addFirst(new SimpleCommandLinePropertySource(args));
}
}
}
protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
Set<String> profiles = new LinkedHashSet(this.additionalProfiles);
profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
environment.setActiveProfiles(StringUtils.toStringArray(profiles));
}
2.5.1 webApplicationType 枚举类
public enum WebApplicationType {
NONE,
SERVLET,
REACTIVE;
private static final String[] SERVLET_INDICATOR_CLASSES = new String[]{"javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext"};
private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";
private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";
private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";
private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
private WebApplicationType() {
}
// SpringApplication类初始化的时候调用该值,来判断应用类型
static WebApplicationType deduceFromClasspath() {
// 当DispatcherHandler存在,且DispatcherServlet和ServletContainer不存在时,
// 说明此时应用是反应式web应用
if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {
return REACTIVE;
} else {
// SERVLET_INDICATOR_CLASSES 是web应用的一些必须有的类名,进行校验,如果有不存在的说明当前是None模式
String[] var0 = SERVLET_INDICATOR_CLASSES;
int var1 = var0.length;
for(int var2 = 0; var2 < var1; ++var2) {
String className = var0[var2];
if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
return NONE;
}
}
return SERVLET;
}
}
static WebApplicationType deduceFromApplicationContext(Class<?> applicationContextClass) {
if (isAssignable("org.springframework.web.context.WebApplicationContext", applicationContextClass)) {
return SERVLET;
} else {
return isAssignable("org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext", applicationContextClass) ? REACTIVE : NONE;
}
}
private static boolean isAssignable(String target, Class<?> type) {
try {
return ClassUtils.resolveClassName(target, (ClassLoader)null).isAssignableFrom(type);
} catch (Throwable var3) {
return false;
}
}
}
2.5.2 单例模式获取ConversionService
public class ApplicationConversionService extends FormattingConversionService {
private static volatile ApplicationConversionService sharedInstance;
public ApplicationConversionService() {
this((StringValueResolver)null);
}
public ApplicationConversionService(StringValueResolver embeddedValueResolver) {
if (embeddedValueResolver != null) {
this.setEmbeddedValueResolver(embeddedValueResolver);
}
configure(this);
}
//懒汉模式创建实例:在使用到的地方再创建
public static ConversionService getSharedInstance() {
ApplicationConversionService sharedInstance = ApplicationConversionService.sharedInstance;
if (sharedInstance == null) {
Class var1 = ApplicationConversionService.class;
synchronized(ApplicationConversionService.class) {
sharedInstance = ApplicationConversionService.sharedInstance;
if (sharedInstance == null) {
sharedInstance = new ApplicationConversionService();
ApplicationConversionService.sharedInstance = sharedInstance;
}
}
}
return sharedInstance;
}
}
2.6 创建应用上下文
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch(this.webApplicationType) {
case SERVLET:
contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
break;
case REACTIVE:
contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
break;
default:
contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
}
} catch (ClassNotFoundException var3) {
throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
}
}
//使用默认的构造器初始化对象
return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
}
2.7 Context处理 -prepareContext
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
//将environment 信息放入context
context.setEnvironment(environment);
//上下文中创建单例的beanNameGenerator,resourceLoader,addConversionService
this.postProcessApplicationContext(context);
// 将ApplicationContextInitializer 放入context
this.applyInitializers(context);
//将监听器初始化放入context中
listeners.contextPrepared(context);
// 判断是否要记录启动日志
if (this.logStartupInfo) {
this.logStartupInfo(context.getParent() == null);
this.logStartupProfileInfo(context);
}
//上下文获取一个bean工厂
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//将启动的时候带入的参数,单例注册bean
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
Set<Object> sources = this.getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 将context内的类、包、source进行加载
this.load(context, sources.toArray(new Object[0]));
//监听器到上下问加载的步骤
listeners.contextLoaded(context);
}
2.7.1 处理应用上下文,根据beanNameGenerator、resourceLoader 、addConversionService
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
if (this.beanNameGenerator != null) {
context.getBeanFactory().registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator", this.beanNameGenerator);
}
if (this.resourceLoader != null) {
if (context instanceof GenericApplicationContext) {
((GenericApplicationContext)context).setResourceLoader(this.resourceLoader);
}
if (context instanceof DefaultResourceLoader) {
((DefaultResourceLoader)context).setClassLoader(this.resourceLoader.getClassLoader());
}
}
if (this.addConversionService) {
context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());
}
}
2.7.2 将ApplicationContextInitializer初始化放入应用上下文中
protected void applyInitializers(ConfigurableApplicationContext context) {
Iterator var2 = this.getInitializers().iterator();
while(var2.hasNext()) {
ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
}
}
2.8 Context处理 -refreshContext
private void refreshContext(ConfigurableApplicationContext context) {
this.refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
} catch (AccessControlException var3) {
}
}
}
protected void refresh(ApplicationContext applicationContext) {
//检查类型正确
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext)applicationContext).refresh();
}
AbstractApplicationContext.refresh()
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
// 准备refresh
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (this.logger.isDebugEnabled()) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Refreshing " + this);
} else {
this.logger.debug("Refreshing " + this.getDisplayName());
}
}
//init property
this.initPropertySources();
//验证需要的properties 是否存在,不存在就抛出异常
this.getEnvironment().validateRequiredProperties();
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
this.earlyApplicationEvents = new LinkedHashSet();
}
}