springboot 的启动流程(二)
本文主要讲述 applicationcontext的refresh方法。
在上一篇说了在applicationcontext的预处理阶段之后,开始对其进行刷新工作。
这里把我们的applicationcontext转成了 AbstractApplicationContext ,并调用了其refresh方法。
public void refresh() throws BeansException, IllegalStateException { # 整个方法被一个synchronized 包裹住了,保证了线程安全。 synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
1. prepareRefresh()
这里又是对applicationcontext的预处理工作。之前在那个run方法里已经有一个预处理的过程了,只不过那个是
prepareContext,那个时候是对applicationcontext设置了environment,注册了一些必要的单实例bean,做了一些applicationcontext的初始化工作,触发监听器等。而这里是applicationcontext的prepareRefresh,做了一些预刷新工作。(也就是说之前是在applicationcontext类的外部前后做了一些处理,这里是其内部做的一些处理)。
/** * Prepare this context for refreshing, setting its startup date and * active flag as well as performing any initialization of property sources. * 注释说的很清楚了 */ protected void prepareRefresh() { # 设置启动日期 this.startupDate = System.currentTimeMillis(); # 设置状态 this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { # 打印 logger.info("Refreshing " + this); } // Initialize any placeholder property sources in the context environment # 这里面默认什么也没做,空方法,留作扩展用 initPropertySources(); // Validate that all properties marked as required are resolvable // see ConfigurablePropertyResolver#setRequiredProperties # 这里是对environment里的属性进行了验证 getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... # 继续,还是赋值操作 this.earlyApplicationEvents = new LinkedHashSet<>(); }
2.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
这里注释为告知子类刷新其内部 的beanfactory,然后获取了当前的applicationcontext的beanfactory,并返回回去。
是一个 ConfigurableListableBeanFactory
3. prepareBeanFactory(beanFactory); 对这个beanfactory做了一些预处理工作。
这里也是为beanfactory的一些属性设置值,比如设置classloader,后置处理器(post-processors)等。
4. postProcessBeanFactory(beanFactory);
这里对beanfactory做了一些后置处理
比如我们使用了springmvc,会有子容器,对子容器做了一些工作等。
5. invokeBeanFactoryPostProcessors(beanFactory);
这里开始调用了beanfactory的后置处理器
按照指定的顺序实例化并且调用所有的beanfactorypostprocesser。
6. registerBeanPostProcessors(beanFactory);
这里开始注册bean的后置处理器,它的作用是拦截bean的创建,会生成bean的代理对象来代替。(spring aop)
和beanfactorypostprocesser类似,,这里按照指定的顺序实例化并且调用所有的beanpostprocesser。
7. initMessageSource();
这里就是初始化了一些messagesources,注册一些bean。
8. initApplicationEventMulticaster
初始化事件的多播器,用于在applicationcontext中广播事件。
9. onRefresh
在这里会初始化子容器的一些bean,,比如springmvc内的bean
这个是springmvc中的applicationcontext( org.springframework.web.context.support.GenericWebApplicationContext )
10. registerListeners
注册了其他的我们自己实现的applicationlistener
/** * Add beans that implement ApplicationListener as listeners. * Doesn't affect other listeners, which can be added without being beans. */ 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); } } }
11 . finishBeanFactoryInitialization
这里最后实例化剩下的单实例的bean
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ 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(); }
12. finishRefresh 完成applicationcontext的刷新工作
/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * {@link org.springframework.context.event.ContextRefreshedEvent}. */ 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. # 发布applicationcontext刷新完成的事件 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
到这里我们的applicationcontext就完成了刷新工作,spring对bean(包括factorybean)划分成了各个阶段(也就是bean生命周期,包括bean信息的定义,bean对应的class的加载,实例化前后(是否需要生成其代理对象,aop,事务等功能),初始化阶段(属性赋值)前后,以及最后的销毁阶段),让我们更方便的去对bean做处理,使用上也更加灵活,也方便于对其他框架的整合,使用。