作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可。

最近由于工作和生活,学习耽搁了几天,今天我们继续接着上一章,分析FileSystemXmlApplicationContext的构造函数,到底都做了什么,导致IOC容器初始化成功。

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException { super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}

我们跟踪上一章FileSystemXmlApplicationContext的构造函数,可以发现它最终调用的是上面这个形式重载的构造函数,其中的refresh方法,便是IOC容器初始化的入口。下面我们继续跟踪代码进去看一下refresh方法。refresh方法位于AbstractApplicationContext中,这是一个抽象类,初步实现了ApplicationContext的一般功能,并且这里使用了模板模式,给以后要实现的子类提供了统一的模板。

public void refresh() throws BeansException, IllegalStateException {
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) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans(); // Reset 'active' flag.
cancelRefresh(ex); // Propagate exception to caller.
throw ex;
}
}
}

这里面列出了IOC容器初始化的大致步骤,第一步很容易看出来是初始化准备,这个方法里只是设置了一个活动标识,我们主要来看第二步,obtainFreshBeanFactory这个方法,它是用来告诉子类刷新内部的bean工厂,接下来我们跟踪进去看看。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}

该方法中第一句便调用了另外一个refreshBeanFactory方法,这个方法是AbstractApplicationContext中的抽象方法,具体的实现并没有在这个抽象类中实现,而是留给了子类,我们追踪到这个子类当中去看一下。该方法又子类AbstractRefreshableApplicationContext实现,我们来看

protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
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);
}
}

方法加上了final关键字,也就是说此方法不可被重写,可以很清楚的看到,IOC容器的初始化就是在这个方法里发生的,第一步先是判断有无现有的工厂,有的话便会将其摧毁,否则,就会创建一个默认的bean工厂,也就是前面提到的DefaultListableBeanFactory,注意看loadBeanDefinitions(beanFactory);这里,当我们创建了一个默认的bean工厂以后,便是载入bean的定义。这与我们上一章所使用的原始的创建bean工厂的方式极为相似。

看到这里,其实不难看出,FileSystemXmlApplicationContext的初始化方法中,其实已经包含了我们上一章当中原始的创建过程,这个类是一个现有的,spring已经为我们实现好的BeanFactory的实现类。在项目当中,我们经常会用到。

今天天色已晚,改天鄙人带着各位去看一下IOC容器建立的要义,也就是载入bean定义的实现。

spring源码学习之路---深度分析IOC容器初始化过程(四)的更多相关文章

  1. spring源码学习之路---深入AOP(终)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...

  2. Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点

    Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...

  3. spring源码学习之路---IOC初探(二)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...

  4. spring源码学习之路---AOP初探(六)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近工作很忙,但当初打算学习 ...

  5. spring源码学习之路---环境搭建(一)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近已经开始了spring源 ...

  6. spring源码学习之路---IOC实现原理(三)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章我们已经初步认识了Be ...

  7. spring源码学习之路---IOC容器初始化要义之bean定义载入(五)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近工作很忙,时间不多,研究 ...

  8. Spring源码学习

    Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...

  9. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

随机推荐

  1. xml解析方法总结

    ==========================================xml文件<?xml version=”1.0″ encoding=”GB2312″?> <RES ...

  2. 使用zookeeper实现分布式锁

    简介: 核心是解决资源竞争的问题 分布式系统中经常需要协调多进程或者多台机器之间的同步问题,得益于zookeeper,实现了一个分布式的共享锁,方便在多台服务器之间竞争资源时,来协调各系统之间的协作和 ...

  3. php判断访问的当前设备是手机还是电脑

    <?php function isMobile(){ $useragent=isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AG ...

  4. Parallel.js初探

    今天闲着看了一下Parallel.js.这个库暂时貌似还没有什么中文的介绍(可能暂时用的人都不多吧).所以就只能上github找它得源码和介绍看看了.貌似它的代码也不多,以后可以深入研究一下. 先简单 ...

  5. shell判断文件是否存在

    转自:http://www.cnblogs.com/sunyubo/archive/2011/10/17/2282047.html 1. shell判断文件,目录是否存在或者具有权限 2. #!/bi ...

  6. VR 相关专业词汇

    最近在看 SIGGRAPH2015 有关 VR Display and Interaction 的几篇文章,之前从来没看过有关方面的 paper,一看才发现专业词汇太多了,根本不懂啊,幸亏 Paper ...

  7. 允许webservice远程测试

    System.Web节点下添加 <webServices> <protocols> <add name= "HttpPost"/> <ad ...

  8. 利用canvas实现抽奖转盘---转载别人的

    功能需求 转盘要美观,转动效果流畅. 转盘上需要显示奖品图片,并且奖品是后台读取的照片和名字. 转动动画完成后要有相应提示. 获取的奖品具体算法在数据库里操作,前端只提供最后的效果展示.   知识要点 ...

  9. ThinkPHP去重 distinct和group by

    转自:http://blog.csdn.net/helencoder/article/details/50328629 近期项目中,遇到数据表去重要求,对于ThinkPHP的去重有了更加准确的认识和体 ...

  10. Redis 的 5 个常见使用场景

    2015-07-22 23:31:46 本文由 伯乐在线 - 刘晓鹏 翻译,黄利民 校稿.未经许可,禁止转载!英文出处:Joe Engel.欢迎加入翻译组. 在这篇文章中,我们将阐述 Redis 最常 ...