2019独角兽企业重金招聘Python工程师标准>>>

Spring的Ioc容器其实就是一个bean的关系网,依赖于core,bean,context三个组件来构建的。在spring中最核心的就是对于bean的管理。而bean又依托于我们的容器。本文将从顶层分析一下spring中beanFactory的具体创建过程,为后续的bean的生命周期提供一个基础。 BeanFactory的继承体系

从上图可以看到,BeanFactory有三个子类:ListableBeanFactory

HierarchicalBeanFactory

AutowireCapableBeanFactory

(上述三个类的子类体系小伙伴们可以自己对着源码看下,实在太多)

看下上图中最底层的DefaultListableBeanFactory类的定义:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable

这个其实就是BeanFactory的默认实现类,它直接或者间接的实现了所有的接口。其实在看spring源码的时候都会遇到类似的设计模式,对于某一个具体的功能,通常都会定义很多层的接口,层层包装,层层委托。这种做法的好处就是,对于不同的场合都会有特定的接口;这样一来就可以在spring内部对对象的传递和转化操作都会有一些访问限制。 例如ListableBeanFactory接口表示这些Bean是可列表的,而HierarchicalBeanFactory表示的是这些Bean是有继承关系的,也就是每个Bean有可能有父Bean。AutowireCapableBeanFactory接口定义Bean的自动装配规则。这四个接口共同定义了Bean的集合、Bean之间的关系、以及Bean行为。

BeanFactory的创建

在之前的文章中说过了容器的刷新过程。BeanFactory的创建也在wac.refresh()方法中。具体看下到底是通过哪些子类来完成的:

// 通知子类刷新内部的bean工厂。 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

1.AbstractApplicationContext中的obtainFreshBeanFactory

下面是obtainFreshBeanFactory的方法逻辑:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //这个是具体创建的方法,由子类实现 refreshBeanFactory(); //获取BeanFactory实例对象(ConfigurableListableBeanFactory类型的) ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }

refreshBeanFactory并未有具体的实现逻辑,这个方法主要是通过委托给子类的refreshBeanFactory方法来实现,在AbstractApplicationContext中refreshBeanFactory是一个抽象模板方法:

protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

2.refreshBeanFactory方法(AbstractRefreshableApplicationContext类中):

下面只注释与beanFactory创建相关的代码

protected final void refreshBeanFactory() throws BeansException { //是否已经有BeanFactory了 if (hasBeanFactory()) { //销毁原有的Bean destroyBeans(); //关闭工厂 closeBeanFactory(); } try { //创建一个新的beanFactory 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); } }

这个方法是实现执行这个上下文的底层bean工厂的实际刷新,如果有的话之前有BeanFactory存在,则关闭以前的bean工厂。并为上下文生命周期的下一个阶段初始化一个新鲜的bean工厂。

3.createBeanFactory(AbstractRefreshableApplicationContext类中)

protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); }

这个方法就是为当前上下文创建一个内部的bean工厂。每次调用refresh()方法是都会创建尝试创建。默认实现是创建一个DefaultListableBeanFactory。并通过getInternalParentBeanFactory()获取内部bean工厂来作为父级bean工厂。可以在子类中重写,例如自定义DefaultListableBeanFactory的设置。

getInternalParentBeanFactory(AbstractApplicationContext类中)

protected BeanFactory getInternalParentBeanFactory() { return (getParent() instanceof ConfigurableApplicationContext) ? ((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent(); }

4.DefaultListableBeanFactory的构造函数

/**

* 通过给定的父类创建一个新的DefaultListableBeanFactory容器

* @param parentBeanFactory the parent BeanFactory

*/

public DefaultListableBeanFactory(BeanFactory parentBeanFactory) { super(parentBeanFactory);

}

super(parentBeanFactory)调用的是AbstractAutowireCapableBeanFactory的构造函数

/**

* 通过给定的父类构建新的AbstractAutowireCapableBeanFactory

* @param parentBeanFactory parent bean factory, or {@code null} if none

*/

public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {

this();

//设置父工厂

setParentBeanFactory(parentBeanFactory);

}

this(),还是AbstractAutowireCapableBeanFactory的构造函数:

/**

* 构建一个新的AbstractAutowireCapableBeanFactory.

*/

public AbstractAutowireCapableBeanFactory() {

super();

ignoreDependencyInterface(BeanNameAware.class);

ignoreDependencyInterface(BeanFactoryAware.class);

ignoreDependencyInterface(BeanClassLoaderAware.class);

}

super() ; AbstractBeanFactory的构造函数

/**

* 构建一个新的AbstractBeanFactory.

*/

public AbstractBeanFactory() {

}

转载于:https://my.oschina.net/u/3959468/blog/2052399

Spring源码系列:BeanFactory的创建相关推荐

  1. Spring源码系列(十二)Spring创建Bean的过程(二)

    1.写在前面 上篇博客主要Spring在创建Bean的时候,第一次调用的Bean的后置处理器的过程,同时笔者也打算将整个Spring创建的Bean的过程,通过这个系列,将Bean的创建过程给讲清楚,废 ...

  2. Spring源码系列:依赖注入(二)createBean

    在Spring源码系列:依赖注入(一)(AbstractBeanFactory-getBean)最后说道getBean是依赖注入的起点,bean的创建都是通过createBean来完成具体的创建的.c ...

  3. Ioc容器beanDefinition-Spring 源码系列(1)

    Ioc容器beanDefinition-Spring 源码系列(1) 目录: Ioc容器beanDefinition-Spring 源码(1) Ioc容器依赖注入-Spring 源码(2) Ioc容器 ...

  4. Spring源码系列- Spring Beans - 核心类的基本介绍

    Spring源码系列- Spring Beans - 核心类的基本介绍 读过上一篇文章的读者应该都能对Spring的体系结构有一个大致的了解,在结尾处,我也说过会从spring-beans包开始分析, ...

  5. 【spring源码系列-05】refresh中prepareRefresh方法的执行流程

    Spring源码系列整体栏目 内容 链接地址 [一]spring源码整体概述 https://blog.csdn.net/zhenghuishengq/article/details/13094088 ...

  6. Spring源码系列:BeanDefinition载入(下)

    在Spring源码系列:BeanDefinition载入(上)中已经大概捋了一下解析过程,本篇将记录一下bean的注册过程. bean的注册就是DefaultListableBeanFactory中r ...

  7. Spring源码系列-第1章-Spring源码纵览【持续更新中】

    文章目录 必读 第1章-Spring源码纵览 概述 简单的继承关系图 Spring框架整体流程 核心组件接口分析 Resource资源 方法 实现类 ResourceLoader资源加载器 方法 实现 ...

  8. Spring源码系列(十三)——Spring源码编译及详细注解

    文章目录 1. 环境搭建 2. 代码编译 2.1 编译代码 2.1.1 build.gradle 2.1.1.1 第一处 2.1.1.2 第二处 2.1.2 gradle.properties 2.1 ...

  9. spring源码系列一--BeanDefinition

    如果说java是由对象组成,那么spring-framework框架可以说是由BeanDefinition所构成.BeanDefinitiion其实是spring中的顶级接口,我们在阅读源码之前必须要 ...

最新文章

  1. android+busybox+编译,Android版busybox编译
  2. tp5 保存图片背景黑色_少女心背景图 | 风环绕世界百圈,不如见你时心动
  3. vc编程的ime输入法菜单开发
  4. c语言一本书的页码从自然数1开始顺序编码,C++_关于统计数字问题的算法,一本书的页码从自然数1开始顺 - phpStudy...
  5. 如何在线下载哔哩哔哩上的视频
  6. 外贸大宗商品行业ERP管理解决方案
  7. 企业信用代码等常用的正则验证
  8. python 安卓王者荣耀刷金币
  9. Linux scp和sftp
  10. IMTOKEN 2.9.9官网1:1双端,用户管理系统,后台可查询用户使用情况
  11. 基于JPEG压缩编码的数据压缩算法的研究与实现(转)
  12. 数字证书及公钥、私钥
  13. 一天到晚只会抱怨的人必定是不成熟的人
  14. 蓝桥杯 — IAP15F2K61S2-89C52 转换板说明文件
  15. 生存曲线 p值 python_超详细讲解生信SCI中的生存曲线作图,不看后悔系列
  16. 深入解析 DataGrid 过滤功能
  17. Nor Flash笔记--看一图看懂并学会计算Flash大小
  18. 联想微型计算机C200配置,联想C200一体电脑基本配置
  19. 公务员碑文辞职书走红,以教堂碑文为铭改变生活
  20. win10taskkill强行结束进程_批处理文件BAT找到进程PID并强制结束TaskKill进程

热门文章

  1. c++ 纯虚函数导出
  2. 1019. 链表中的下一个更大节点
  3. Linux日常运维管理技巧(三)iptables规则备份和恢复、firewalld的9个zone、任务计划cron、chkconfig系统服务管理、添加服务命令、systemctl管理服务
  4. Shell通过过滤条件(比如IP)分类流量包,最后合并流量包
  5. ROS kinetic外接Realsense D435i跑ORB_SLAM2教程
  6. 对HashMap对象的键值对内容进行排序
  7. 如何解决comctl32.dll文件丢失的问题?
  8. 支付宝支付系统繁忙,请稍后再试(ALI64)错误解决
  9. 有限自动机的构造与识别
  10. 自定义JPA之AttributeConverter