spring启动过程之源码跟踪(上)--spring Debug
1,初始化容器
1 ClassPathXmlApplicationContext context=new 2 ClassPathXmlApplicationContext("/applicationContext.xml");
步骤1:构造方法如下:
1 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) 2 throws BeansException { 3 super(parent); 4 setConfigLocations(configLocations); 5 if (refresh) { 6 refresh(); 7 } 8 }
步骤2:重头戏到了!
1 public void refresh() throws BeansException, IllegalStateException { 2 synchronized (this.startupShutdownMonitor) { 3 // Prepare this context for refreshing. 4 prepareRefresh(); 5 6 // Tell the subclass to refresh the internal bean factory. 7 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 8 9 // Prepare the bean factory for use in this context. 10 prepareBeanFactory(beanFactory); 11 12 try { 13 // Allows post-processing of the bean factory in context subclasses. 14 postProcessBeanFactory(beanFactory); 15 16 // Invoke factory processors registered as beans in the context. 17 invokeBeanFactoryPostProcessors(beanFactory); 18 19 // Register bean processors that intercept bean creation. 20 registerBeanPostProcessors(beanFactory); 21 22 // Initialize message source for this context. 23 initMessageSource(); 24 25 // Initialize event multicaster for this context. 26 initApplicationEventMulticaster(); 27 28 // Initialize other special beans in specific context subclasses. 29 onRefresh(); 30 31 // Check for listener beans and register them. 32 registerListeners(); 33 34 // Instantiate all remaining (non-lazy-init) singletons. 35 finishBeanFactoryInitialization(beanFactory); 36 37 // Last step: publish corresponding event. 38 finishRefresh(); 39 } 40 41 catch (BeansException ex) { 42 // Destroy already created singletons to avoid dangling resources. 43 beanFactory.destroySingletons(); 44 45 // Reset 'active' flag. 46 cancelRefresh(ex); 47 48 // Propagate exception to caller. 49 throw ex; 50 } 51 } 52 }
步骤3:获取beanFactory
1 protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { 2 refreshBeanFactory(); 3 ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 4 5 if (logger.isInfoEnabled()) { 6 logger.info("Bean factory for application context [" + getId() + "]: " + 7 ObjectUtils.identityToString(beanFactory)); 8 } 9 if (logger.isDebugEnabled()) { 10 logger.debug(beanFactory.getBeanDefinitionCount() + " beans defined in " + this); 11 } 12 13 return beanFactory; 14 }
步骤3-1
1 protected final void refreshBeanFactory() throws BeansException { 2 if (hasBeanFactory()) { 3 destroyBeans(); 4 closeBeanFactory(); 5 } 6 try { 7 DefaultListableBeanFactory beanFactory = createBeanFactory(); 8 customizeBeanFactory(beanFactory); 9 loadBeanDefinitions(beanFactory); 10 synchronized (this.beanFactoryMonitor) { 11 this.beanFactory = beanFactory; 12 } 13 } 14 catch (IOException ex) { 15 throw new ApplicationContextException( 16 "I/O error parsing XML document for application context [" + getDisplayName() + "]", ex); 17 } 18 }
步骤3-2 加载beans的定义(AbstractXmlApplicationContext.java)
1 /** 2 * Loads the bean definitions via an XmlBeanDefinitionReader. 3 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader 4 * @see #initBeanDefinitionReader 5 * @see #loadBeanDefinitions 6 */ 7 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException { 8 // Create a new XmlBeanDefinitionReader for the given BeanFactory. 9 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); 10 11 // Configure the bean definition reader with this context's 12 // resource loading environment. 13 beanDefinitionReader.setResourceLoader(this); 14 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); 15 16 // Allow a subclass to provide custom initialization of the reader, 17 // then proceed with actually loading the bean definitions. 18 initBeanDefinitionReader(beanDefinitionReader); 19 loadBeanDefinitions(beanDefinitionReader); 20 }
步骤3-3
1 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { 2 Resource[] configResources = getConfigResources(); 3 if (configResources != null) { 4 reader.loadBeanDefinitions(configResources); 5 } 6 String[] configLocations = getConfigLocations(); 7 if (configLocations != null) { 8 reader.loadBeanDefinitions(configLocations); 9 } 10 }
步骤3-4 XmlBeanDefinitionReader.java
1 public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { 2 Assert.notNull(encodedResource, "EncodedResource must not be null"); 3 if (logger.isInfoEnabled()) { 4 logger.info("Loading XML bean definitions from " + encodedResource.getResource()); 5 } 6 7 Set currentResources = (Set) this.resourcesCurrentlyBeingLoaded.get(); 8 if (currentResources == null) { 9 currentResources = new HashSet(4); 10 this.resourcesCurrentlyBeingLoaded.set(currentResources); 11 } 12 if (!currentResources.add(encodedResource)) { 13 throw new BeanDefinitionStoreException( 14 "Detected recursive loading of " + encodedResource + " - check your import definitions!"); 15 } 16 try { 17 InputStream inputStream = encodedResource.getResource().getInputStream(); 18 try { 19 InputSource inputSource = new InputSource(inputStream); 20 if (encodedResource.getEncoding() != null) { 21 inputSource.setEncoding(encodedResource.getEncoding()); 22 } 23 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); 24 } 25 finally { 26 inputStream.close(); 27 } 28 } 29 catch (IOException ex) { 30 throw new BeanDefinitionStoreException( 31 "IOException parsing XML document from " + encodedResource.getResource(), ex); 32 } 33 finally { 34 currentResources.remove(encodedResource); 35 if (currentResources.isEmpty()) { 36 this.resourcesCurrentlyBeingLoaded.set(null); 37 } 38 } 39 }
步骤3-5 读取xml文件
DefaultBeanDefinitionDocumentReader.java
1 /** 2 * Parses bean definitions according to the "spring-beans" DTD. 3 * <p>Opens a DOM Document; then initializes the default settings 4 * specified at <code><beans></code> level; then parses 5 * the contained bean definitions. 6 */ 7 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { 8 this.readerContext = readerContext; 9 10 logger.debug("Loading bean definitions"); 11 Element root = doc.getDocumentElement(); 12 13 BeanDefinitionParserDelegate delegate = createHelper(readerContext, root); 14 15 preProcessXml(root); 16 parseBeanDefinitions(root, delegate); 17 postProcessXml(root); 18 }
(以下图片为网上所得,非原创,谢谢原作者)
创建 BeanFactory 时序图
解析和登记 Bean 对象时序图
转载于:https://www.cnblogs.com/davidwang456/archive/2013/03/11/2954563.html
spring启动过程之源码跟踪(上)--spring Debug相关推荐
- spring启动过程之源码跟踪(下)--spring Debug
在web应用启动入口是ContextLoaderListener,它是怎么完成启动过程的呢? 首先: public class ContextLoaderListenerextends Object ...
- spring启动过程之源码跟踪(小结bean的生命周期)--spring Debug
spring in action 1.容器发现bean的定义,初始化bean 2.使用依赖注入的方式,spring根据bean定义,设置bean的所有属性 3.如果bean继承了BeanNameAwa ...
- spring启动过程之源码跟踪(中)--spring Debug
上节我们debug到 1 // Tell the subclass to refresh the internal bean factory. 2 ConfigurableListableBeanFa ...
- spring启动过程之源码跟踪(续beanfactory)--spring Debug
1.初始化过程 1 Resource res = new ClassPathResource("/applicationContext.xml"); 2 XmlBeanFactor ...
- spring session spring:session:sessions:expires 源码跟踪
2019独角兽企业重金招聘Python工程师标准>>> spring session spring:session:sessions:expires 源码跟踪 博客分类: sprin ...
- spring依赖注入_Spring源码阅读:Spring依赖注入容器
依赖注入 依赖注入是Spring框架最核心的能力,Spring框架提供的AOP,WebMVC等其它功能都是以依赖注入容器作为基础构建的,Spring依赖注入容器类似于一个用于组装对象的框架内核,任何应 ...
- spring 启动之全过程 源码解析
主类代码 public class BeanLifeCycle {public static void main(String[] args) {System.out.println("现在 ...
- Spring IoC容器初始化源码(1)—容器初始化入口以及setConfigLocations设置容器配置信息【一万字】
基于最新Spring 5.x,对于基于XML的Spring IoC容器初始化过程中的setConfigLocations设置容器配置信息方法的源码进行了详细分析,最后给出了比较详细的方法调用时序图 ...
- spring boot 2.0 源码分析(三)
通过上一章的源码分析,我们知道了spring boot里面的listeners到底是什么(META-INF/spring.factories定义的资源的实例),以及它是创建和启动的,今天我们继续深入分 ...
最新文章
- 转: 用css把图片转为灰色图
- HIVE的安装配置、mysql的安装、hive创建表、创建分区、修改表等内容、hive beeline使用、HIVE的四种数据导入方式、使用Java代码执行hive的sql命令
- 手机鸿蒙公测选择一个应用,鸿蒙系统公测半个月,首批“差评”很难听,但是却也很真实...
- JS_arguments
- 互联网晚报 | 3月26日 星期六 |​ 竞拍规则优化,部分城市土地市场有所回暖;​​武汉房贷利率下调...
- python查找文件内容_python实现搜索文本文件内容脚本
- CentOS升级Python到2.7版本
- 小数第n位java_蓝桥杯【历届试题 小数第n位】 java版 数论
- Sublime个性化配置
- Java基础知识强化之IO流笔记59:打印流
- 6.企业安全建设入门(基于开源软件打造企业网络安全) --- 代码审计
- 如何用微信建立打卡小程序(做打卡签到小程序方法)
- SAP-物料 X 未对销售组织 XXXX 分销渠道 X 语言 XX 定义
- 计算机网络电子邮件的基本格式,怎样的格式才是正确的电子邮件格式?
- uniapp uniCloud 云开发上传图片与查看图片
- 软件开发V模型--解读
- 年入800万!韩国第一虚拟网红的崛起
- 转:PL/0语言词法及语法分析系统的设计与实现
- Struts2 官方教程之Struts Tags(六)——Generic Tags(Control Tags )
- GPS定位原理及应用简介
热门文章
- php销毁three.js量,javascript – ThreeJS:从场景中删除对象
- datetime 取分钟_如何仅从DateTime获取小时和分钟
- 小学计算机管理员培训,中小学计算机管理员培训心得体会-20210401075623.docx-原创力文档...
- mysql 5.5 5.6 主从_mysql5.6+主从集的版本号(mysql5.5主机和从机载带后,5.5在设置有一定的差距)...
- 数据库常用语句(日常填充)
- php编程查错,盘点PHP编程常见失误
- c++ 交换变量实践
- 97. Leetcode 剑指 Offer 60. n个骰子的点数 (动态规划-背包问题)
- pytorch错误解决: BrokenPipeError: [Errno 32] Broken pipe
- 论文笔记:Temporal Regularized Matrix Factorization forHigh-dimensional Time Series Prediction