Spring源码解析-IOC容器的实现
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结构图
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容器的实现的更多相关文章
- Spring源码解析-ioc容器的设计
Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...
- Spring源码解析-IOC容器的实现-ApplicationContext
上面我们已经知道了IOC的建立的基本步骤了,我们就可以用编码的方式和IOC容器进行建立过程了.其实Spring已经为我们提供了很多实现,想必上面的简单扩展,如XMLBeanFacroty等.我们一般是 ...
- Spring 源码剖析IOC容器(一)概览
目录 一.容器概述 二.核心类源码解读 三.模拟容器获取Bean ======================= 一.容器概述 spring IOC控制反转,又称为DI依赖注入:大体是先初始化bean ...
- Spring源码阅读-IoC容器解析
目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...
- Spring源码解析--IOC根容器Beanfactory详解
BeanFactory和FactoryBean的联系和区别 BeanFactory是整个Spring容器的根容器,里面描述了在所有的子类或子接口当中对容器的处理原则和职责,包括生命周期的一些约定. F ...
- [spring源码] 小白级别的源码解析IOC容器的依赖注入(三)
上一篇介绍了ioc容器的初始化过程,主要完成了ioc容器建立beanDefinition数据映射.并没有看到ioc容器对bean依赖关系进行注入. 接口getbean就是出发依赖注入发生的地方.下面从 ...
- Spring源码解析 – AnnotationConfigApplicationContext容器创建过程
Spring在BeanFactory基础上提供了一些列具体容器的实现,其中AnnotationConfigApplicationContext是一个用来管理注解bean的容器,从AnnotationC ...
- spring源码解析——2容器的基本实现(第2版笔记)
感觉第二版写的略潦草,就是在第一版的基础上加上了新的流行特性,比如idea,springboot,但是,潦草痕迹遍布字里行间. 虽然换成了idea,但是很多截图还是eclipse的,如果不是看了第一版 ...
- SPRING源码分析:IOC容器
在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...
随机推荐
- ACM对拍程序
1.把所需对拍的代码的可执行文件a.exe b.exe放在同一目录下 2.把rand数据的代码的可执行文件c.exe放在该目录下 3.新建一个txt文件,里面添加代码,后把格式改成bat @echo ...
- org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.my.service.ProductService] for bean with name 'productService' defi报错解决方法
原 javaweb项目报错org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [XXX] ...
- Atom插件无法下载安装解决办法,Atom使用教程,Atom常用插件
使用教程http://wiki.jikexueyuan.com/project/atom/plug-in.html atom通过setting中无法下载插件,通过apm也无法下载插件,可能是网络.co ...
- [转]tomcat之一:指定tomcat运行时JDK版本
今天在做项目的时候,主管让我在本机上启动多个tomcat且指定不同的jdk环境.因为在企业的项目中个,对于同一个服务器中有多个jdk和tomcat,所以就需要手动指定不同的jdk. 在网上找了很多资料 ...
- 在使用Kafka过程中遇到的错误
问题一:用kafka命令发送消息时候,一直报WARN Error while fetching metadata with correlation id 0 : {test=UNKNOWN_TOPIC ...
- [NOI2014]动物园(kmp)
题目 https://www.luogu.org/problemnew/show/P2375 做法 查找多少个前缀与后缀配对,其实就是\(fail\)树的深度 而不可重叠,其实\(i\)不可用的,\( ...
- getJson同步
$.ajaxSettings.async = false;//在执行之前加$.ajaxSettings.async = false; (同步执行) function get_no_order_ar ...
- chrome中,BackstopJS 使用cookie文件后依旧提示需要登录
1. 本地环境: apache-tomcat:7.05,jdk8, backstopJS:latest-version 配置tomcat管理用户成功:手工访问tomcat应用内部服务正常: 2. 问 ...
- [BZOJ]BST again
Description 求有多少棵大小为n的深度为h的二叉树.(树根深度为0:左右子树有别:答案对1000000007取模) Input 第一行一个整数T,表示数据组数. 以下T行,每行2个整数n和h ...
- JAVA基础补漏--泛型通配符
泛型通配符只能用于方法的参数 不能用对象定义 public class Test { public static void main(String[] args) { ArrayList<Str ...