(五)SpringBoot启动过程的分析-刷新ApplicationContext (7)

当前类中没有实现,只是作为一个模板,将由子类来实现

// AbstractApplicationContext.java protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. } // ServletWebServerApplicationContext.java protected void onRefresh() { // 父类中仅仅设置了一下主题,无关紧要 super.onRefresh(); try { // 创建Web服务器 createWebServer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start web server", ex); } } 创建Web服务器

这里只简单介绍一下它启动了内置的Web容器,Web容器的初始化后续会有单独篇章分析。

private void createWebServer() { // ① WebServer webServer = this.webServer; // ② ServletContext servletContext = getServletContext(); // ③ if (webServer == null && servletContext == null) { ServletWebServerFactory factory = getWebServerFactory(); this.webServer = factory.getWebServer(getSelfInitializer()); } // ④ else if (servletContext != null) { try { getSelfInitializer().onStartup(servletContext); } catch (ServletException ex) { throw new ApplicationContextException("Cannot initialize servlet context", ex); } } // ⑤ initPropertySources(); }

① - 当前应用的WEB服务器,也就是Servlet容器。
② - 当前应用的上下文,一个应用使用一个ServletContext来表示。
③ - 使用ServletWebServerFactory创建一个Servlet容器
④ - 手动配置上下文的接口。
⑤ - 初始化配置信息,实际上就是将环境信息中的'servletContextInitParams':StubPropertySource 转换为'servletContextInitParams': ServletContextPropertySource; 将 'servletConfigInitParams': StubPropertySource转换为'servletConfigInitParams':ServletConfigPropertySource

registerListeners()

主要用于将获取到的所有监听器委托给applicationEventMulticaster。

protected void registerListeners() { // ① // Register statically specified listeners first. for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // ② // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // ③ // Publish early application events now that we finally have a multicaster... Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }

① - 将内部注册的监听器委托给广播器applicationEventMulticaster。
② - 检测BeanFactory内部的监听器
③ - 发布早期事件

finishBeanFactoryInitialization()

实例化剩下的所有单例Bean(非延迟加载的)

// AbstractApplicationContext.java protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // ① // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // ② // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // ③ // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // ④ // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // ⑤ // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // ⑤ // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }

① - 判断是否有转换服务
② - 判断是否有占位符解析器
③ - 注册LoadTimeWeaverAware
④ - 停止使用临时的ClassLoader进行类型匹配,实际上它就是空值
⑤ - 冻结所有的BeanDefinition,通过configurationFrozen = true 和 frozenBeanDefinitionNames(包含所有的BeanDefinition)配合锁定
⑥ - 实例化剩下的所有单例Bean(非延迟加载的),其实就是从注册器缓存里面取出(DefaultSingletonBeanRegistry)

finishRefresh() // ServletWebServerApplicationContext.java @Override protected void finishRefresh() { // 父类执行finishRefresh super.finishRefresh(); // 启动web容器 WebServer webServer = startWebServer(); if (webServer != null) { // 发布web容器启动完成事件 publishEvent(new ServletWebServerInitializedEvent(webServer, this)); } } // AbstractApplicationContext.java protected void finishRefresh() { // ① Clear context-level resource caches (such as ASM metadata from scanning). clearResourceCaches(); // ② Initialize lifecycle processor for this context. initLifecycleProcessor(); // ③ Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // ④ Publish the final event. publishEvent(new ContextRefreshedEvent(this)); // ⑤ Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzszw.html