ioc源码记录

Spring IoC容器spring

IoC容器主要做用就是建立并管理Bean对象以及Bean属性注入。如何建立Bean对象?是经过读取Bean配置文件生成相应对象。这些配置文件格式可能多种多样,xml、properties等格式,因此须要将其转换(ResourceLoader/Resolver)成统一资源对象(Resource),存储的位置也不同,多是ClassPath,多是FileSystem,也多是URL路径,路径的不同,说明的是应用环境可能不同。得到Resource对象,还要将其转换成(BeanDefinitionReader)Spring内部对Bean的描述对象(BeanDefinition),而后,将其注册(BeanRegister)到容器中(BeanFactory),供之后转换成Bean对象使用。设计模式

因此,IoC容器包括了不少东西,但主要有如下六个组件:网络

1.资源组件:Resource,对资源文件的描述,不一样资源文件如xml、properties文件等,格式不一样,最终都将被ResourceLoader加载得到相应的Resource对象;数据结构

        我的理解是  主配置文件   主配置做为全部配置的入口 工具

2.资源加载组件:ResourceLoader:加载xml、properties等各种格式文件,解析文件,并生成Resource对象。设计

        加载哪些解析过的配置资源xml

3.Bean容器组件:BeanFactory体系:IoC容器的核心,其余组件都是为它工做的(但不是仅仅为其服务).对象

                    核心继承

4.Bean注册组件:SingletonBeanRegister/AliasRegister:将BeanDefinition对象注册到BeanFactory(BeanDefinition Map)中去。接口

        注册对象所使用的容器

5.Bean描述组件:BeanDefinition体系,Spring内部对Bean描述的基本数据结构

        负责描述BeanDefinition资源   将资源形式的bean转化为spring所指望的格式结构

6.Bean构造组件:BeanDefinitionReader体系,读取Resource并将其数据转换成一个个BeanDefinition对象。

            负责将一个个的资源 解析转化为BeanDefinition  为以后描述bean作准备

 

 

 

这里组件的定义是相对于IoC容器而言,通常这里的组件设计包括一组接口、一组抽象类、一组实现类、异常类、工具类组成,至于为何要这么设计,能够参考下设计模式的七大原则。

这些组件并非互相独立的,而是相互联系造成一个极其复杂的类关系网,下图摘取的组件类关系图只是摘取比较纯粹(比较高层)的那一部分(好比,就ApplicationContext这种比较中层的对象而言,既是ResourceLoader组件,也是BeanFactory组件一部分,还有其余的,越底层其成分越复杂,功能对应的也越具体,其实质就是一个抽象到具体的过程,但这种抽象不是纯粹的抽象到具体,更掺杂有多种抽象的结合。另外,摘取的图来源Spring 3.2.7)。

下面依次对各个组件作详细说明:

1.资源组件,Resource体系,信息的载体,如各种型的文件,二进制流数据都是资源,是Spring内部对资源的一种统一描述,整个体系类图网以下:(图中名称前面 I 表明是接口,C表示实体类,C中左上角有四分之一扇形绿色的表示是抽象类,虚线表示实现,实线表示继承,下同)

每个实体类表明一种资源类型,好比ClassPathResource表示类加载路径上的资源,FileSystemResource表示文件系统上的资源,UrlResource则是表示网络资源。这是Spring对资源访问策略的一种实现,

总的来讲,Java有本身的对资源访问策略的实现,好比Path,File,URI/URL类等,但有缺点或有不足,Spring就本身弄了一套,能够粗略的认为Spring在Java基础上封装了一层(就像UrlResource,其源码内部就是经过URI/URL实现的),增长了一些功能,更加方便点。

2.资源加载组件,ResourceLoader/Resolver体系,负责资源的加载,这里的资源指的是xml、properties等文件资源,返回一个对应类型的Resource对象。

同Resource对应,不一样的实现类加载不一样的Resource,返回对应的Resource对象,

3.Bean描述组件,BeanDefinition体系,是对bean对象描述的基本数据结构。

4.Bean构造组件,BeanDefinitionReader体系,将Resource对象,转换成BeanDefinition对象,就是将内部资源数据转换成Spring Bean描述数据。其实这种读取数据转换成内部对象的,不只仅是Spring专有的,好比:Dom4j解析器

SAXReader reader = new SAXReader(); Document doc = reader.read(ur.getFile());//ur是一个URLResource对象

严格来讲,都是Reader体系吧,就是将统一资源数据对象读取转换成相应内部对象。

5.Bean注册组件,将BeanDefinition对象注册到BeanFactory中去。

6.Bean容器组件,整个IoC容器核心,所谓Bean容器,就是这里装着Bean对象以及所须要的各类数据。其中BeanFactory是纯粹的Bean容器,用来存储描述Bean,无关其余环境,而像ApplicationContext,也是Bean容器,但它和应用环境息息相关,因此被称为应用上下文(环境)更恰当,从图中也能看出来,ApplicationContext不只有着BeanFactory“血统”,同时也继承了EnvironmentCapable、MessageSource、ApplicationEventPublisher,即扩展了其许多额外功能,而其实现类则是和具体应用相关了,好比ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、WebApplicationContext,从字面上就不难理解其做用。BeanFactory和ApplicationContext的详细区别,能够自行查询。

这里下面这句代码为例子,描述整个工做流程。

ApplicationContext context = new ClassPathXmlApplicationContext(path);

0.新建ApplicationContext容器对象(并无初始化);

1.ResourceLoader加载并解析资源文件 ———> 得到Resource对象;

2.BeanDefinitionReader读取Resource对象,将其读到的bean元素数据封装到BeanDefinition组件中;

3.BeanDefinitionRegister将全部的BeanDefinition注册到BeanFactory中(BeanDefinition是容器内部Bean的基本数据结构,BeanFactory维持着一个BeanDefinition Map);

4.容器初始化开始,容器初始化工做由AbstractApplicationContext提供的refresh()方法完成,具体初始化步骤能够参考下一节:Spring IoC容器初始化。

整个流程大致归纳以下:

至此,context做为应用环境上下文功能完成,程序此后就能够经过context的getBean(String beanName)方法得到path文件声明定义的bean对象。

相关文章
相关标签/搜索