打上断点进行调试

1 第一步是进入了ClassPathXmlApplicationContext调用其构造参数,其中配置文件的内容被解析成了数组

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[]{configLocation}, true, (ApplicationContext)null);}//上面的构造器内部调用的就是以下这个构造器
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {super(parent);//自动配置文件所在的位置this.setConfigLocations(configLocations);if (refresh) {//此处所有的单实例bean创建完成,我们继续进入refresh方法内进行研究this.refresh();}
}

//3 第三步用来分析refresh(),此处所有的单实例bean创建完成

public void refresh() throws BeansException, IllegalStateException {
//this.startupShutdownMonitors是类中定义的一个用专门于同步的锁对象,同步多线程ioc容器的创建于销毁,即保证多线程下ioc只能被创建一次synchronized(this.startupShutdownMonitor) {
//刷新容器this.prepareRefresh();//通过解析spring.xml配置文件创建了beanFactory对象,它的内部获取了组件的基本信息并保存在了beanDefinitionMap中,通过它来创建组件对象,解析的原理主要就是通过反射ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//此时bean工厂已准备好,配置文件已被解析this.prepareBeanFactory(beanFactory);try {//加载bean工厂的后置处理器this.postProcessBeanFactory(beanFactory);//执行beanFactory的后置处理器this.invokeBeanFactoryPostProcessors(beanFactory);//注册bean工厂的后置处理器this.registerBeanPostProcessors(beanFactory);//用于支持国际化功能this.initMessageSource();//初始化容器多事件转发器this.initApplicationEventMulticaster();//留给子类(开发中)自己写容器时进行扩展实现this.onRefresh();//注册spring内部监听器this.registerListeners();//完成beanFactory的初始化 => 所有单实例对象加载完毕,我们需要对该方法进一步研究this.finishBeanFactoryInitialization(beanFactory);this.finishRefresh();} catch (BeansException var9) {......} finally {......}}
}

该方法可以理解为初始化所有单实例bean

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));}if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver((strVal) -> {return this.getEnvironment().resolvePlaceholders(strVal);});}String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);String[] var3 = weaverAwareNames;int var4 = weaverAwareNames.length;for(int var5 = 0; var5 < var4; ++var5) {String weaverAwareName = var3[var5];this.getBean(weaverAwareName);}beanFactory.setTempClassLoader((ClassLoader)null);beanFactory.freezeConfiguration();//主要研究这个放beanFactory.preInstantiateSingletons();
}

只要不是抽象bean,不是多实例bean,不是懒加载,就通过this.getBean(beanName);
获取对象

public void preInstantiateSingletons() throws BeansException {
//日志处理if (this.logger.isTraceEnabled()) {this.logger.trace("Pre-instantiating singletons in " + this);}//拿到所有bean组件的名字放到list中然后继续遍历,其中beanDefinitionNames中具有容器中全部组件的详细信息,如名字、作用域、是否抽象....List<String> beanNames = new ArrayList(this.beanDefinitionNames);Iterator var2 = beanNames.iterator();//顺序遍历bean组件,所以实际开发中bean对象的创建顺序与它们在容器中的顺序一致while(true) {String beanName;Object bean;do {while(true) {RootBeanDefinition bd;do {do {do {if (!var2.hasNext()) {var2 = beanNames.iterator();while(var2.hasNext()) {beanName = (String)var2.next();Object singletonInstance = this.getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged(() -> {smartSingleton.afterSingletonsInstantiated();return null;}, this.getAccessControlContext());} else {smartSingleton.afterSingletonsInstantiated();}}}return;}beanName = (String)var2.next();bd = this.getMergedLocalBeanDefinition(beanName);//创建条件1:组件不能是抽象的} while(bd.isAbstract());//创建条件1:组件不能是抽象的} while(!bd.isSingleton());} while(bd.isLazyInit());if (this.isFactoryBean(beanName)) {bean = this.getBean("&" + beanName);break;}this.getBean(beanName);}/*FactoryBean是Spring中工厂模式应用案例,继承FactoryBean的pojo类返回的不是该类的pojo对象,而是pojo内部重写的FactoryBean的getObject方法中返回的对象*/} while(!(bean instanceof FactoryBean));FactoryBean<?> factory = (FactoryBean)bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {SmartFactoryBean var10000 = (SmartFactoryBean)factory;((SmartFactoryBean)factory).getClass();isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());} else {isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();}if (isEagerInit) {this.getBean(beanName);}}
}

//调用getBean实际就是调用AbstractBeanFactory子类的doGetBean方法

public Object getBean(String name) throws BeansException {return this.doGetBean(name, (Class)null, (Object[])null, false);
}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
//获取组件名String beanName = this.transformedBeanName(name);
/*
先从已注册的单实例bean中,也就是单例池中,查看有无这个组件,没有就先创建,后续再次创建直接从单例池中拿即可
*/Object sharedInstance = this.getSingleton(beanName);Object bean;bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);} else {if (this.isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}BeanFactory parentBeanFactory = this.getParentBeanFactory();if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {String nameToLookup = this.originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}if (args != null) {return parentBeanFactory.getBean(nameToLookup, args);}if (requiredType != null) {return parentBeanFactory.getBean(nameToLookup, requiredType);}return parentBeanFactory.getBean(nameToLookup);}if (!typeCheckOnly) {
//标记bean已经被创建this.markBeanAsCreated(beanName);}try {RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);this.checkMergedBeanDefinition(mbd, beanName, args);
//拿到这个bean的依赖bean并先于该bean创建这个组件String[] dependsOn = mbd.getDependsOn();String[] var11;
//循环创建这个bean所依赖的组件对象if (dependsOn != null) {var11 = dependsOn;int var12 = dependsOn.length;for(int var13 = 0; var13 < var12; ++var13) {String dep = var11[var13];if (this.isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}this.registerDependentBean(dep, beanName);try {this.getBean(dep);} catch (NoSuchBeanDefinitionException var24) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);}}}//如果是单例模式if (mbd.isSingleton()) {
//创建单例beansharedInstance = this.getSingleton(beanName, () -> {try {return this.createBean(beanName, mbd, args);} catch (BeansException var5) {this.destroySingleton(beanName);throw var5;}});bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}

//真正的创建组件对象的方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized(this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");}if (this.logger.isDebugEnabled()) {this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}this.beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = this.suppressedExceptions == null;if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet();}try {
//此处获取到单例bean对象singletonObject = singletonFactory.getObject();newSingleton = true;} catch (IllegalStateException var16) {singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throw var16;}} catch (BeanCreationException var17) {BeanCreationException ex = var17;if (recordSuppressedExceptions) {Iterator var8 = this.suppressedExceptions.iterator();while(var8.hasNext()) {Exception suppressedException = (Exception)var8.next();ex.addRelatedCause(suppressedException);}}throw ex;} finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}this.afterSingletonCreation(beanName);}//如果是新建的单例对象,就将其加入到单例池中if (newSingleton) {this.addSingleton(beanName, singletonObject);}}return singletonObject;}
}

Spring IOC容器和获取组件对象源码分析相关推荐

  1. Spring IOC和Bean生命周期以及源码分析

    这篇文章主要讲解 IOC 容器的创建过程,让大家对整体有一个全局的认识,文章目录如图: 1. 基础知识 1.1 什么是 Spring IOC ? IOC 不是一种技术,只是一种思想,一个重要的面向对象 ...

  2. java 从一个容器获取对象,如何从 Spring IoC 容器中获取对象?

    前面几篇文章主要分析了 Spring IoC 容器如何初始化,以及解析和注册我们定义的 bean 信息. 其中,「Spring 中的 IoC 容器」对 Spring 中的容器做了一个概述,「Sprin ...

  3. java使用websocket,并且获取HttpSession,源码分析

    一:本文使用范围 此文不仅仅局限于spring boot,普通的spring工程,甚至是servlet工程,都是一样的,只不过配置一些监听器的方法不同而已. 本文经过作者实践,确认完美运行. 二:Sp ...

  4. java 获取httpsession_java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  5. 《微信小程序-进阶篇》Lin-ui组件库源码分析-列表组件List(一)

    大家好,这是小程序系列的第二十篇文章,在这一个阶段,我们的目标是 由简单入手,逐渐的可以较为深入的了解组件化开发,从本文开始,将记录分享lin-ui的源码分析,期望通过对lin-ui源码的学习能加深组 ...

  6. Spring自定义注解驱动开发使用及源码分析

    目录 前言 注解驱动开发使用 需求 代码实现 测试效果 源码分析 BeanDefinitionRegistryPostProcessor接口 解析BeanDefinition 处理Bean上配置的注解 ...

  7. 动态代理最全详解系列[2]-Proxy生成代理类对象源码分析

      之前我们通过JDK中的Proxy实现了动态代理,Proxy用起来是比较简便的,但理解起来不是那么清晰,是因为我们并没有看见代理类是怎么生成的,代理类怎么调用的被代理类方法,所以下面我们进入源码看一 ...

  8. 聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)

    每篇一句 唯有热爱和坚持,才能让你在程序人生中屹立不倒,切忌跟风什么语言或就学什么去~ 相关阅读 [小家Spring]聊聊Spring中的数据转换:Converter.ConversionServic ...

  9. 聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)【享学Spring】

    每篇一句 唯有热爱和坚持,才能让你在程序人生中屹立不倒,切忌跟风什么语言或就学什么去~ 前言 数据绑定 这个概念在任何一个成型的框架中都是特别重要的(尤其是web框架),它能让框架更多的自动化,更好容 ...

最新文章

  1. 横向ListView(一) ——开篇,基础逻辑实现
  2. 斐波那契数列性质【记住】
  3. pandas移除dataframe字符串数据列中的后N个字符(remove the last n characters from values from column of dataframe)
  4. IntelliJ IDEA Groovy(转)
  5. 西北工业大学附属中学2019届高考毕业生去向,其中北大清华88人
  6. linux sed给空文件首行插入_Sed命令高级功能,学好了工作不愁
  7. XCTF WEB view_source
  8. 用栈和递归求解迷宫问题
  9. C++工作笔记-对二级指针的进一步理解(获取调用者的地址)
  10. Spark API编程动手实战-08-基于IDEA使用Spark API开发Spark程序-01
  11. 疑似华为P50系列7月29日发布:麒麟9000旗舰芯片加持
  12. mysql checkpoint_MySQL checkpoint深入分析
  13. 众觅,让支付宝『到位』全国到位
  14. STM32单片机开发板 定制
  15. 响铃:金蝶的SaaS第一能保持多久?
  16. ctf镜子里面的世界_一个小编姐姐的CTF入坑之旅
  17. Python爬虫爬取古诗文网站项目分享
  18. python openpyxl操作Excel表格
  19. STM32-(ADC,DMA,重映射)
  20. Flutter开发日志——初生牛犊

热门文章

  1. jquery查找元素方法示例
  2. .NET Framework 工具下载
  3. 合格架构师的目标管理
  4. axios的基本用法
  5. 前端工程师需要懂的前端面试题(c s s方面)总结(二)
  6. 如果用float实现居中
  7. android程序表白,几条曲线构建Android表白程序
  8. java 输出字符串的所有排列_JAVA 输出指定字符串所有排列组合
  9. java 字符串拆分技巧_在java中如何拆分一个字符串?
  10. servlet3.1