Spring源码解析-IOC容器的实现

时间:2022-09-30 10:40:48

1.IOC容器是什么?

   IOC(Inversion of Control)控制反转:本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫控制反转,即交给了IOC容器,Spring的IOC容器主要使用DI方式实现的。不需要主动查找,对象的查找、定位和创建全部由容器管理。

在程序中不创建对象。以前我们要调用一个对象的方法,首先要new一个对象。但使用IOC容器,在代码中不直接与对象连接,而是在配置文件中描述要使用哪一个对象。容器负责将这些联系在一起。

  IOC容器的基本功能规范是由BeanFactory定义的,也就是说,BeanFactory定义了IOC容器的最基本的形式,并提供了IOC容器所应该遵守的最基本的服务准则。也是我们使用IOC容器最基本的规范.在Spring的代码中,BeanFactory只是一个借口类,并没有给出容器的具体实现,我们可以看到各种具体的实现,如XmlBeanFactory,ApplicationContext。。 下面是BeanFactory的代码:(如下解释)

  package org.springframework.beans.factory;
  import org.springframework.beans.BeansException;
  public interface BeanFactory {

  //在这里我们可以通过转义字符"&"去得到FactoryBean本身,用来区分通过容器来获得FactoryBean产生的对象和获取FactoryBean本身
     String FACTORY_BEAN_PREFIX = "&";

//得到相应的bean  通过bean的名称
    Object getBean(String name) throws BeansException;

/**

  *得到相应的bean,通过bean的名称和所属的类型
    */
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

/**

*得到相应的bean  通过所属的类型
    */
    <T> T getBean(Class<T> requiredType) throws BeansException;

/**
    得到bean     通过bean的名称和相应的检索的类型要求
     */
    Object getBean(String name, Object... args) throws BeansException;

/**
     判断是否包含某个bean
     */
    boolean containsBean(String name);

/**
     来查询指定的bean是否为singleton类型的bean   对于相应的属性可以在BeanDefinition中指定
     */
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

/**
    来查询指定的bean是否为prototype类型的bean   对于相应的属性可以在BeanDefinition中指定
     */
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

/**
     查询指定的名称的bean的class类型是不是特定的class类型  class类型可以使用户自己定义
     */
    boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;

/**
     查询指定名称的bean的class类型
     */
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

/**
   查询指定了名称bean的所有的别名  这些别名都是在BeanDefinition中定义的
     */
    String[] getAliases(String name);

}

2.IOC容器XmlBeanFactory的工作原理

  这个图是相应XmlBeanFactory结构图

Spring源码解析-IOC容器的实现

  XmlBeanFactory只提供了最基本的IOC容器的功能,这个IOC容器可以读取以XML形式定义的BeanDefinition。XmlBeanFactory怎么实现Xml读取的?对这些XML文件定义信息的处理并不是由XmlBeanFactory直接处理。在XmlBeanFactory中,初始化了一个XmlBeanDefinitionReader对象,之所以有了XmlBeanDefinitionReader,XmlBeanFactory就可以那些一xml方式定义的BeanDefinition,所以xml的处理其实是由XmlBeanDefinitionReader来处理的。构建这个XmlBeanFactory需要指定BeanDefinition的数据来源,看下面源码应该很清楚了,是有spring的resource类来给出的。resource是spring封装的io操作的类。如下面例子:

  ClassPathResource resource = new ClassPathResource("applicationContext.xml");这样具体的ClassPathResource类构造相应的resource,然后作为构造参数传递给XmlBeanFactory,这样就可以通过BeanDefinition定义相应的bean进行容器的初始化和依赖注入的过程了。

XmlBeanFactory的源码如下:

package org.springframework.beans.factory.xml;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.io.Resource;

//这个类继承的DefaultListableBeanFactory,这个类包含了IOC容器的重要功能,在很多地方都会用到。
public class XmlBeanFactory extends DefaultListableBeanFactory {
    private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
    /**
     传入一个Resource,进行加载xml形式定义的BeanDefinition
     */
    public XmlBeanFactory(Resource resource) throws BeansException {
        this(resource, null);
    }

/**
     传入一个Resource,进行加载xml形式定义的BeanDefinition   及其相依的BeanFactory对象进行加载
     */
    public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
        super(parentBeanFactory);
        this.reader.loadBeanDefinitions(resource);
    }

}
使用例子:

ClassPathResource resource = new ClassPathResource("applicationContext.xml");

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

XmlBeanDefinitionReader read = new XmlBeanDefinitionReader(factory);

read.loadBeanDefinitions(resource);

这样我就可以通过factory对象来使用DefaultListableBeanFactory这个IOC容器了。相应的步骤:

1.创建IOC配置文件的抽象资源,其中包含相应bean的定义。

2.创建一个BeanFactory

3.创建一个载入BeanDefinition的读取器,通过一个回调配置给BeanFactory

4.从定义好的资源位置读入配置信息,完成整个载入和注册相应的bean定义之后,IOC容器就可以使用了。

Spring源码解析-IOC容器的实现的更多相关文章

  1. Spring源码解析-ioc容器的设计

    Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...

  2. Spring源码解析-IOC容器的实现-ApplicationContext

    上面我们已经知道了IOC的建立的基本步骤了,我们就可以用编码的方式和IOC容器进行建立过程了.其实Spring已经为我们提供了很多实现,想必上面的简单扩展,如XMLBeanFacroty等.我们一般是 ...

  3. Spring 源码剖析IOC容器(一)概览

    目录 一.容器概述 二.核心类源码解读 三.模拟容器获取Bean ======================= 一.容器概述 spring IOC控制反转,又称为DI依赖注入:大体是先初始化bean ...

  4. Spring源码阅读-IoC容器解析

    目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...

  5. Spring源码解析--IOC根容器Beanfactory详解

    BeanFactory和FactoryBean的联系和区别 BeanFactory是整个Spring容器的根容器,里面描述了在所有的子类或子接口当中对容器的处理原则和职责,包括生命周期的一些约定. F ...

  6. &lbrack;spring源码&rsqb; 小白级别的源码解析IOC容器的依赖注入&lpar;三&rpar;

    上一篇介绍了ioc容器的初始化过程,主要完成了ioc容器建立beanDefinition数据映射.并没有看到ioc容器对bean依赖关系进行注入. 接口getbean就是出发依赖注入发生的地方.下面从 ...

  7. Spring源码解析 – AnnotationConfigApplicationContext容器创建过程

    Spring在BeanFactory基础上提供了一些列具体容器的实现,其中AnnotationConfigApplicationContext是一个用来管理注解bean的容器,从AnnotationC ...

  8. spring源码解析——2容器的基本实现(第2版笔记)

    感觉第二版写的略潦草,就是在第一版的基础上加上了新的流行特性,比如idea,springboot,但是,潦草痕迹遍布字里行间. 虽然换成了idea,但是很多截图还是eclipse的,如果不是看了第一版 ...

  9. SPRING源码分析&colon;IOC容器

    在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...

随机推荐

  1. 字典树 - A Poet Computer

    The ACM team is working on an AI project called (Eih Eye Three) that allows computers to write poems ...

  2. php使用curl简单抓取远程url的方法

    这篇文章主要介绍了php使用curl简单抓取远程url的方法,涉及php操作curl的技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了php使用curl抓取远程url的方法.分 ...

  3. &lbrack;原&rsqb;OpenGL基础教程(五)缓冲区数据更新方式

    1.glBufferSubData 适用于相同数据类型 void SetPositionY(float y){    vector<Vector3<float>>::itera ...

  4. Java缓存学习之一:缓存

    一.缓存 1.什么是缓存? 缓存是硬件,是CPU中的组件,CPU存取数据的速度非常的快,一秒钟能够存取.处理十亿条指令和数据(术语:CPU主频1G),而内存就慢很多,快的内存能够达到几十兆就不错了,可 ...

  5. AVR单片机RC触摸

    RC电容触摸感应按键1:RC感应原理 RC采样原理就是通过测量感应极电容的微小变化,来感知人体对电容式感应器(按键.轮键或者滑条)的感应.电极电容(C)通过一个固定的电阻(R)周期性地充放电.(原文件 ...

  6. 阿里云ecs遭到频繁的ddos攻击始末

    苦逼熬夜近俩月的时间搞出来个小东东,还指望它能给自己捞点~  结果刚上线没多久就遭到竞争对手疯狂的ddos攻击. 可怜的阿里云默认只能抗住5G的攻击,超出的直接黑洞,也是很无奈,然而能免费抗5G这在国 ...

  7. ant&lowbar;&lowbar;&lowbar;令牌过滤器

    令牌过滤器允许我们在复制时过滤文件中的数据.要进行过滤,需要使用一个必须与过滤器任务中的@token @设置匹配的标记.任务使用@作为标记分隔符.为了实现此功能,apache ant提供了使用toke ...

  8. Django HTTP&lowbar;X&lowbar;FORWARDED&lowbar;FOR 和 REMOTE&lowbar;ADDR

    使用django来获取用户访问的IP地址,如果用户是正常情况下 request.META['REMOTE_ADDR'] 可以获得用户的IP地址.但是有些网站服务器会使用ngix等代理http,或者是该 ...

  9. CodeForces 459C Pashmak and Buses(构造)题解

    题意:n个人,k辆车,要求d天内任意两人都不能一直在同一辆车,能做到给出构造,不能输出-1 思路:我们把某一个人这d天的车号看成一个d位的数字,比如 1 1 2 3代表第一天1号车.第二天1号车.第三 ...

  10. 【LeetCode】135&period; Candy

    Candy There are N children standing in a line. Each child is assigned a rating value. You are giving ...