ioc源码记录

Spring IoC容器

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对象。

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

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做准备

 

144501_Aj7h_3618851.png

 

 

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

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

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

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

144509_0PT1_3618851.png

每一个实体类代表一种资源类型,比如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构144515_aZW9_3618851.png造组件,BeanDefinitionReader体系,将Resource对象,转换成BeanDefinition对象,就是将内部资源数据转换成Spring Bean描述数据。其实这种读取数据转换成内部对象的,不仅仅是Spring专有的,比如:Dom4j解析器

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

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

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

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

144541_5m8D_3618851.png

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

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对象。

转载于:https://my.oschina.net/u/3618851/blog/1588479

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值