當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
spring生命周期_理解Spring应用上下文生命周期
生活随笔
收集整理的這篇文章主要介紹了
spring生命周期_理解Spring应用上下文生命周期
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- Spring應用上下文啟動準備階段
- `BeanFactory`創建階段
- `BeanFactory`準備階段
- `BeanFactory`后置處理階段
- `AnnotationConfigServletWebApplicationContext#postProcessBeanFactory`
- `AbstractApplicationContext#invokeBeanFactoryPostProcessors`
- `BeanFactory`注冊`BeanPostProcessor`階段
- 初始化內建Bean: `MessageSource`
- 初始化內建Bean : Spring事件廣播器
- Spring應用上下文刷新階段
- Spring事件監聽器注冊階段
- `getApplicationEventMulticaster`
- `AbstractApplicationEventMulticaster#addApplicationListener`
- `BeanFactory`初始化完成階段
- 凍結配置
- 初始化非延遲單例 Bean
- Spring應用上下文刷新完成階段
- 清除ResourceLoader緩存
- 初始化LifecycleProcessor對象
- 調用LifecycleProcessor#onRefresh方法
- 發布Spring應用上下文已刷新事件
- 向MBeanServer 托管Live Beans(JMX)
- Spring應用上下文啟動階段
- Spring應用上下文停止階段
- Spring應用上下文關閉階段
- `AbstractApplicationContext#doClose`
- `removeShutdownHook`
- 面試題
- Spring應用上下文生命周期有哪些階段
- Environment完整的生命周期
- Spring應用上下文生命周期執行動作
Spring應用上下文生命周期
AbstractApplicationContext#refresh是Spring應用上下文生命周期的入口方法 @Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.// Spring應用上下文啟動準備階段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();}}}Spring應用上下文啟動準備階段
AbstractApplicationContext#prepareRefresh/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
// 默認是空實現,供子類實現
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
- 啟動時間 startupDate
- 狀態標識
this.closed.set(false); this.active.set(true); - 初始化PropertySources
空方法,供子類實現,通常會提早創建Environment - 檢驗Environment中必須屬性
- 初始化事件監聽器集合
- 初始化早期Spring事件集合
BeanFactory創建階段
AbstractApplicationContext#obtainFreshBeanFactory/*** Tell the subclass to refresh the internal bean factory.* @return the fresh BeanFactory instance* @see #refreshBeanFactory()* @see #getBeanFactory()*/protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();// 返回BeanFactoryreturn getBeanFactory();}AbstractRefreshableApplicationContext#refreshBeanFactory
/*** This implementation performs an actual refresh of this context's underlying* bean factory, shutting down the previous bean factory (if any) and* initializing a fresh bean factory for the next phase of the context's lifecycle.*/@Overrideprotected final void refreshBeanFactory() throws BeansException {// 判斷是否創建了BeanFactory ,是的話 銷毀Bean,關閉BeanFactoryif (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {// 創建BeanFactoryDefaultListableBeanFactory beanFactory = createBeanFactory();// 設置idbeanFactory.setSerializationId(getId());// 設置是否允許BeanDefinition 重復定義 , 設置是否允許循環依賴customizeBeanFactory(beanFactory);// 加載beanDefinitionloadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}- AbstractApplicationContext#obtainFreshBeanFactory
- AbstractRefreshableApplicationContext#refreshBeanFactory
- 如果BeanFactory已經創建好了,就關閉或銷毀BeanFactory
- createBeanFactory()
- beanFactory.setSerializationId
- customizeBeanFactory(beanFactory)
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
// 設置是否允許BeanDefinition 重復定義
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 設置是否允許循環依賴
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
} - loadBeanDefinitions(beanFactory)
xml 、注解驅動上下文 的具體實現不同
- getBeanFactory();
- AbstractRefreshableApplicationContext#refreshBeanFactory
BeanFactory準備階段
/*** Configure the factory's standard context characteristics,* such as the context's ClassLoader and post-processors.* @param beanFactory the BeanFactory to configure*/protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.// 關聯ClassLoader (給予xml的上下文之前沒有加載到bean class)beanFactory.setBeanClassLoader(getClassLoader());// 設置Bean表達式處理器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 添加PropertyEditorRegistrar(類型轉換)實現: ResourceEditorRegistrarbeanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 添加Aware回調接口 BeanPostProcessor實現 :ApplicationContextAwareProcessorbeanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 忽略Aware接口作為依賴注入接口beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.// 注冊ResolvableDependency對象beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.// 注冊單例對象 (environment相關)if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}BeanFactory后置處理階段
// Allows post-processing of the bean factory in context subclasses. // 由子類實現postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory); AbstractApplicationContext#refreshprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {}/*** Instantiate and invoke all registered BeanFactoryPostProcessor beans,* respecting explicit order if given.* <p>Must be called before singleton instantiation.*/protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}AnnotationConfigServletWebApplicationContext#postProcessBeanFactory
Servlet Web 注解驅動上下文的實現@Overrideprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 調用父類super.postProcessBeanFactory(beanFactory);if (!ObjectUtils.isEmpty(this.basePackages)) {this.scanner.scan(this.basePackages);}if (!this.annotatedClasses.isEmpty()) {this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));}}1.GenericWebApplicationContext#postProcessBeanFactory
/*** Register ServletContextAwareProcessor.* @see ServletContextAwareProcessor*/@Overrideprotected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {if (this.servletContext != null) {beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));beanFactory.ignoreDependencyInterface(ServletContextAware.class);}WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);}WebApplicationContextUtils#registerWebApplicationScopes(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, javax.servlet.ServletContext)
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,@Nullable ServletContext sc) {// 注冊Scope// requestbeanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());// sessionbeanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());if (sc != null) {// applicationServletContextScope appScope = new ServletContextScope(sc);beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);// Register as ServletContext attribute, for ContextCleanupListener to detect it. // 設置ServletContext Attributesc.setAttribute(ServletContextScope.class.getName(), appScope);}// 注冊ResolvableDependencybeanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());if (jsfPresent) {FacesDependencyRegistrar.registerFacesDependencies(beanFactory);}}WebApplicationContextUtils.registerEnvironmentBeans
注冊Servlet相關的Bean/*** Register web-specific environment beans ("contextParameters", "contextAttributes")* with the given BeanFactory, as used by the WebApplicationContext.* @param bf the BeanFactory to configure* @param sc the ServletContext that we're running within*/public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf, @Nullable ServletContext sc) {registerEnvironmentBeans(bf, sc, null);}public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf,@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);}// servletConfig=nullif (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);}if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {Map<String, String> parameterMap = new HashMap<>();if (servletContext != null) {Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();while (paramNameEnum.hasMoreElements()) {String paramName = (String) paramNameEnum.nextElement();parameterMap.put(paramName, servletContext.getInitParameter(paramName));}}if (servletConfig != null) {Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();while (paramNameEnum.hasMoreElements()) {String paramName = (String) paramNameEnum.nextElement();parameterMap.put(paramName, servletConfig.getInitParameter(paramName));}}bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,Collections.unmodifiableMap(parameterMap));}if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {Map<String, Object> attributeMap = new HashMap<>();if (servletContext != null) {Enumeration<?> attrNameEnum = servletContext.getAttributeNames();while (attrNameEnum.hasMoreElements()) {String attrName = (String) attrNameEnum.nextElement();attributeMap.put(attrName, servletContext.getAttribute(attrName));}}bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,Collections.unmodifiableMap(attributeMap));}}2.ClassPathBeanDefinitionScanner#scan
根據basePackages的內容加載、注冊BeanDefinitionpublic int scan(String... basePackages) {int beanCountAtScanStart = this.registry.getBeanDefinitionCount();doScan(basePackages);// Register annotation config processors, if necessary.if (this.includeAnnotationConfig) {AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart); }AbstractApplicationContext#invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
BeanFactoryPostProcessor回調public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.Set<String> processedBeans = new HashSet<>();if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {// 先處理BeanDefinitionRegistryPostProcessorif (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;// 回調 registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);}else {regularPostProcessors.add(postProcessor);}}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!// Separate between BeanDefinitionRegistryPostProcessors that implement// PriorityOrdered, Ordered, and the rest.List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {// BeanDefinitionRegistryPostProcessor PriorityOrderedif (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.boolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();}// Now, invoke the postProcessBeanFactory callback of all processors handled so far.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();List<String> orderedPostProcessorNames = new ArrayList<>();List<String> nonOrderedPostProcessorNames = new ArrayList<>();for (String ppName : postProcessorNames) {if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...beanFactory.clearMetadataCache();}BeanFactory注冊BeanPostProcessor階段
AbstractApplicationContext#registerBeanPostProcessors主要涉及如下邏輯:
初始化內建Bean: MessageSource
AbstractApplicationContext#initMessageSource protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// Make MessageSource aware of parent MessageSource.if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {// Only set parent context as parent MessageSource if no parent MessageSource// registered already.hms.setParentMessageSource(getInternalParentMessageSource());}}if (logger.isTraceEnabled()) {logger.trace("Using MessageSource [" + this.messageSource + "]");}}else {// Use empty MessageSource to be able to accept getMessage calls.DelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);if (logger.isTraceEnabled()) {logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");}}} 默認情況下會注冊一個DelegatingMessageSource 類型的MessageSource(國際化) singleton Bean初始化內建Bean : Spring事件廣播器
ApplicationEventMulticaster在Spring應用上下文中必須存在
protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);if (logger.isTraceEnabled()) {logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}}else {// 默認注冊SimpleApplicationEventMulticaster Beanthis.applicationEventMulticaster = new SimpleApplicationEventMulticaster Bean(beanFactory);beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);if (logger.isTraceEnabled()) {logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");}}}Spring應用上下文刷新階段
AbstractApplicationContext#onRefresh默認是空方法,供具體的上下文(Web應用)進行自定義擴展
protected void onRefresh() throws BeansException {// For subclasses: do nothing by default.}Spring事件監聽器注冊階段
protected void registerListeners() {// Register statically specified listeners first.// 1.添加當前Spring應用上下文關聯的ApplicationListener對象集合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!// 2. 添加 BeanFactory所注冊的ApplicationListener Beans// 這里不初始化Bean,延遲初始化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...// 廣播早期Spring事件Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}getApplicationEventMulticaster
/*** Return the internal ApplicationEventMulticaster used by the context.* @return the internal ApplicationEventMulticaster (never {@code null})* @throws IllegalStateException if the context has not been initialized yet*/ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {if (this.applicationEventMulticaster == null) {throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +"call 'refresh' before multicasting events via the context: " + this);}return this.applicationEventMulticaster;}AbstractApplicationEventMulticaster#addApplicationListener
@Overridepublic void addApplicationListener(ApplicationListener<?> listener) {// 加鎖 保證多線程操作的原子性synchronized (this.retrievalMutex) {// Explicitly remove target for a proxy, if registered already,// in order to avoid double invocations of the same listener.Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);if (singletonTarget instanceof ApplicationListener) {this.defaultRetriever.applicationListeners.remove(singletonTarget);}this.defaultRetriever.applicationListeners.add(listener);this.retrieverCache.clear();}}BeanFactory初始化完成階段
/*** 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.// BeanFactory 關聯 ConversionService Bean(如果存在)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.// BeanFactory添加StringValueResolver對象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) {// 依賴查找LoadTimeWeaverAware BeangetBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.// 將BeanFactory的臨時ClassLoader置為空beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.// BeanFactory凍結配置beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.// 初始化非延遲單例 BeanbeanFactory.preInstantiateSingletons();}凍結配置
DefaultListableBeanFactory@Overridepublic void freezeConfiguration() {this.configurationFrozen = true;// 凍結 不讓修改的beanDefinition 名稱this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);}初始化非延遲單例 Bean
@Overridepublic void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {// merged BeanDefinitonRootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {final FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}}else {getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}SmartInitializingSingleton#afterSingletonsInstantiated
回調Spring應用上下文刷新完成階段
finishorg.springframework.context.support.AbstractApplicationContext#finishRefresh/*** 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).// 清除ResourceLoader緩存clearResourceCaches();// Initialize lifecycle processor for this context.// 初始化LifecycleProcessor對象initLifecycleProcessor();// Propagate refresh to lifecycle processor first.// 調用LifecycleProcessor.onrefresh方法getLifecycleProcessor().onRefresh();// Publish the final event.// 發布Spring應用上下文已刷新事件publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.// 向MBeanServer 托管Live BeansLiveBeansView.registerApplicationContext(this);}清除ResourceLoader緩存
private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);/*** Clear all resource caches in this resource loader.* @since 5.0* @see #getResourceCache*/public void clearResourceCaches() {this.resourceCaches.clear();}初始化LifecycleProcessor對象
protected void initLifecycleProcessor() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {this.lifecycleProcessor =beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);if (logger.isTraceEnabled()) {logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");}}else {// 默認實現DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();defaultProcessor.setBeanFactory(beanFactory);this.lifecycleProcessor = defaultProcessor;beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);if (logger.isTraceEnabled()) {logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");}}}調用LifecycleProcessor#onRefresh方法
DefaultLifecycleProcessor#onRefresh@Overridepublic void onRefresh() {startBeans(true);this.running = true;} private void startBeans(boolean autoStartupOnly) {// 獲取Lifecycle BeansMap<String, Lifecycle> lifecycleBeans = getLifecycleBeans();Map<Integer, LifecycleGroup> phases = new HashMap<>();// 遍歷lifecycleBeans.forEach((beanName, bean) -> {// 不滿足條件if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {int phase = getPhase(bean);LifecycleGroup group = phases.get(phase);if (group == null) {group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);phases.put(phase, group);}group.add(beanName, bean);}});if (!phases.isEmpty()) {List<Integer> keys = new ArrayList<>(phases.keySet());Collections.sort(keys);for (Integer key : keys) {phases.get(key).start();}}}發布Spring應用上下文已刷新事件
廣播ContextRefreshedEvent事件AbstractApplicationContext#publishEvent下面的源碼就是之前說的ApplicationEventMulticaster給ApplicationEventPublisher(一般為Spring應用上下文)打工的故事protected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");// Decorate event as an ApplicationEvent if necessaryApplicationEvent applicationEvent;if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;}else {applicationEvent = new PayloadApplicationEvent<>(this, event);if (eventType == null) {eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();}}// Multicast right now if possible - or lazily once the multicaster is initializedif (this.earlyApplicationEvents != null) {this.earlyApplicationEvents.add(applicationEvent);}else {getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);}// Publish event via parent context as well...if (this.parent != null) {if (this.parent instanceof AbstractApplicationContext) {((AbstractApplicationContext) this.parent).publishEvent(event, eventType);}else {this.parent.publishEvent(event);}}}
向MBeanServer 托管Live Beans(JMX)
// LiveBeansView.registerApplicationContext static void registerApplicationContext(ConfigurableApplicationContext applicationContext) {// 獲取配置的mbeanDomainString mbeanDomain = applicationContext.getEnvironment().getProperty(MBEAN_DOMAIN_PROPERTY_NAME);if (mbeanDomain != null) {synchronized (applicationContexts) {if (applicationContexts.isEmpty()) {try {// MBeanServerMBeanServer server = ManagementFactory.getPlatformMBeanServer();applicationName = applicationContext.getApplicationName();server.registerMBean(new LiveBeansView(),new ObjectName(mbeanDomain, MBEAN_APPLICATION_KEY, applicationName));}catch (Throwable ex) {throw new ApplicationContextException("Failed to register LiveBeansView MBean", ex);}}applicationContexts.add(applicationContext);}}}Spring應用上下文啟動階段
start 手動觸發 @Overridepublic void start() {getLifecycleProcessor().start();// 發布ContextStartedEvent事件publishEvent(new ContextStartedEvent ContextStartedEvent(this));}Spring應用上下文停止階段
stop 手動觸發@Overridepublic void stop() {getLifecycleProcessor().stop();publishEvent(new ContextStoppedEvent(this));}當我們的Bean實現了LifeCycle接口時,調用Spring應用上下文的start/stop方法,Bean 的start方法和stop方法會隨之調用,這是對Spring上下文生命周期的補充,定義了一種全新的生命周期。
public interface Lifecycle {void start();void stop();boolean isRunning(); }Spring應用上下文關閉階段
close /** Synchronization monitor for the "refresh" and "destroy". */private final Object startupShutdownMonitor = new Object();@Overridepublic void close() {synchronized (this.startupShutdownMonitor) {doClose();// If we registered a JVM shutdown hook, we don't need it anymore now:// We've already explicitly closed the context.if (this.shutdownHook != null) {try {Runtime.getRuntime().removeShutdownHook(this.shutdownHook);}catch (IllegalStateException ex) {// ignore - VM is already shutting down}}}}AbstractApplicationContext#doClose
/** Flag that indicates whether this context is currently active. */ private final AtomicBoolean active = new AtomicBoolean();/** Flag that indicates whether this context has been closed already. */ private final AtomicBoolean closed = new AtomicBoolean();protected void doClose() {// Check whether an actual close attempt is necessary...if (this.active.get() && this.closed.compareAndSet(false, true)) {// 撤銷JMX對Spring Bean的托管LiveBeansView.unregisterApplicationContext(this);try {// Publish shutdown event.// 發布ContextClosedEvent事件publishEvent(new ContextClosedEvent(this));}catch (Throwable ex) {...}// Stop all Lifecycle beans, to avoid delays during individual destruction.if (this.lifecycleProcessor != null) {try {this.lifecycleProcessor.onClose();}catch (Throwable ex) {...}}// Destroy all cached singletons in the context's BeanFactory.destroyBeans();// Close the state of this context itself.closeBeanFactory();// Let subclasses do some final clean-up if they wish...onClose();// Reset local application listeners to pre-refresh state.if (this.earlyApplicationListeners != null) {this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Switch to inactive.this.active.set(false);}}destroyBeans
protected void destroyBeans() {getBeanFactory().destroySingletons(); }closeBeanFactory
removeShutdownHook
優雅宕機總結
以上是生活随笔為你收集整理的spring生命周期_理解Spring应用上下文生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 红米k20防水吗
- 下一篇: 认证服务器的搭建_SpringCloud