前言web
本文转自“天河聊技术”微信公众号spring
今天的主要内容是spring上下文刷新相关源码解析设计模式
正文缓存
跟踪到这个类微信
org.springframework.web.context.ContextLoader#configureAndRefreshWebApplicationContext这行代码并发
// 上下文刷新 wac.refresh();
找到org.springframework.context.ConfigurableApplicationContext#refresh这个接口的一个抽象实现org.springframework.context.support.AbstractApplicationContext#refreshide
@Override public void refresh() throws BeansException, IllegalStateException { // 门面模式,刷新和销毁上下文必须是同步的,这里加了一个锁 synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing.准备这个上下文来刷新。 // 上下文刷新的前置工做 prepareRefresh(); // Tell the subclass to refresh the internal bean factory.初始化内部beanFactory TODO 天河 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(); } } }
总体看下,这个方法采用了门面设计模式,代码看起来跟整洁,逻辑很清晰。post
刷新和销毁上下文必须是同步的,这里加了一个锁ui
synchronized (this.startupShutdownMonitor) {
上下文刷新的前置工做this
prepareRefresh();
跟踪到这个方法
org.springframework.context.support.AbstractApplicationContext#prepareRefresh spring上下文刷新以前的一些前置工做,主要是相关属性的解析
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 // 验证Required的属性 getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); }
返回到这个方法org.springframework.context.support.AbstractApplicationContext#refresh
这一行代码
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
建立beanFactory。
org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory跟踪到这个方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 刷新beanFactory refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
刷新beanFactory
refreshBeanFactory();
跟踪到这个方法org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory 实现了上下文底层的beanFactory刷新,若是以前有beanFactory就关闭并再初始化一个beanFactory。
@Override protected final void refreshBeanFactory() throws BeansException { // 若是存在beanFactory if (hasBeanFactory()) { // 销毁bean destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
判断是否存在beanFactory
if (hasBeanFactory()) { // 销毁bean destroyBeans(); closeBeanFactory(); }
跟踪到这个方法
org.springframework.context.support.AbstractApplicationContext#destroyBeans 销毁单例的bean
protected void destroyBeans() { // 获取beanFactory,并销毁单例的bean TODO 销毁bean getBeanFactory().destroySingletons(); }
找到这个方法
org.springframework.beans.factory.support.DefaultListableBeanFactory#destroySingletons
@Override public void destroySingletons() { super.destroySingletons(); // 清除记录的单例beanName的缓存 this.manualSingletonNames.clear(); clearByTypeCache(); }
第一行代码调用了父类的这个方法
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#destroySingletons
@Override public void destroySingletons() { super.destroySingletons(); // 清空beanFactory缓存 this.factoryBeanObjectCache.clear(); }
第一行代码又调用了父类的这个方法
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingletons
public void destroySingletons() { if (logger.isDebugEnabled()) { logger.debug("Destroying singletons in " + this); } // 这里使用ConcurrentHashMap本地缓存单例的bean实例,访问次数比较多,提搞并发量 synchronized (this.singletonObjects) { this.singletonsCurrentlyInDestruction = true; } String[] disposableBeanNames; // 这里是用LinkedHashMap本地缓存销毁的bean实例 synchronized (this.disposableBeans) { disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); } for (int i = disposableBeanNames.length - 1; i >= 0; i--) { // 销毁单例的bean destroySingleton(disposableBeanNames[i]); } this.containedBeanMap.clear(); this.dependentBeanMap.clear(); this.dependenciesForBeanMap.clear(); // 同步清空缓存 synchronized (this.singletonObjects) { this.singletonObjects.clear(); this.singletonFactories.clear(); this.earlySingletonObjects.clear(); this.registeredSingletons.clear(); this.singletonsCurrentlyInDestruction = false; } }
找到这行代码
destroySingleton(disposableBeanNames[i]);
进入到这个方法
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingleton
public void destroySingleton(String beanName) { // Remove a registered singleton of the given name, if any.删除单例的bean,从本地缓存中删除 removeSingleton(beanName); // Destroy the corresponding DisposableBean instance. DisposableBean disposableBean; synchronized (this.disposableBeans) { // 从本地缓存中删除 disposableBean = (DisposableBean) this.disposableBeans.remove(beanName); } // bean销毁的逻辑 destroyBean(beanName, disposableBean); }
最后
本次介绍到这里,以上内容仅供参考。下次bean销毁的源码解析。