Spring IOC源码学习(一):基本概念
一、Spring IOC基本概念
- org.springframework.beans和org.springframework.context包是Spring Framework的IoC容器的基础
- BeanFactory接口提供了能够管理任何类型的对象的高级配置机制
- ApplicationContext是BeanFactory的子接口。它更容易与Spring的AOP功能集成;消息资源处理(用于国际化),事件发布;以及应用层特定的上下文,例如用于Web应用程序的WebApplicationContext
- BeanFactory提供了配置框架和基本功能,而ApplicationContext增加了更多的企业级功能
- 在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。 bean是一个被Spring IoC容器实例化,组装和以其他方式管理的对象。否则,bean只是应用程序中的许多对象之一。 Bean和它们之间的依赖关系反映在容器使用的配置元数据中
在容器本身中,这些bean定义被表示为BeanDefinition 对象,其中包含(以及其他信息)以下元数据:
- 包限定的类名:通常定义的bean的实际实现类。
- Bean行为配置元素,它说明了Bean在容器中的行为(范围、生命周期回调,等等)。
- 对bean进行工作所需的其他bean的引用;这些引用也称为协作者或依赖项。
- 例如,在新创建的对象中设置的其他配置设置,例如在管理连接池的bean中使用的连接数,或池的大小限制。
元数据(Configuration Metadata)
image.png-
POJOS+Configuration Metadata=Spring Container
Spring Container.png
二、ClassPathXmlApplicationContext层次结构
上面的一些概念应该可以对Spring Container有了一点理论支持,简单的来说,Spring容器就是一个Map,Map中存放的是类和实例的对应关系,但是Spring本身的健壮性和复杂性,不可能单纯的就是一个Map,下图是Spring容器的一个层次关系图,只列出了一些必要的属性,主要的结构就是Context-->BeanFactory-->BeanDefinition,之后的分析也主要会按照这几个类来分析。
context.png
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-ioc.xml");
通过上面代码可以获取到Context的结构:
1、ApplicationContext
2、BeanFactory
image.png3、BeanDefinition
看了这么多的属性越来越看不懂了,但是可以换个思路,把Spring容器当做一个屋子,你屋里面所有的东西都是一个Bean,你的手机,插线板,数据线都是一个Bean,他们之间存在相互依赖的关系,你先给你手机充电,你得知道一些信息,比如:
- 手机在哪
- 手机是什么型号,需要用什么数据线
- 手机还有多少电量
- 充电线在哪
- 屋子里是不是有电
- 充电线是不是好的等等
SpringContext也是一样,如果需要利用Bean,也是需要以很多的上下文信息和Bean的信息,Bean说到底还是一个Class的实例,那实例信息肯定是必不可少的,那实例信息是什么呢?就是实例化赋予该对象的值,就像上图中的beanClass,除此之外,就是一些Bean和Bean的关系,BeanA依赖BeanB,那么dependsNo就派上用场了,Spring将这些配置信息放在了XML中或者是JavaConfig中,就得有这些数据源(source)的信息,那么也就有了resource属性,这里只说了其中的一些,还有很多属性,在之后使用到的时候再具体说。
- 将这些Bean都存放到Context中了,该怎么取出来呢?
UserService userService = context.getBean("userService", UserService.class);
这里就要介绍一个关键的接口了,Spring中的一个原则就是面向接口编程,接口定义规范,子类实现规范,学习Spring,就得先从接口开始。
beanFactory.png可以看到BeanFactory很简单,这也符合Spring的设计原则,对外接口简单,实现复杂,BeanFactory的方法包含两类,Get和Match,对getBean的重载是为了提供更为丰富提取Bean的方式,从getBaen中也可以看得出一点点东西,那就是入参中包含了Aliases,Class,Object,beanName和beanType或者是他们之间的组合,这也反映出来了Spring内部对于Bean定义的一些规则。
BeanFactory需要注意的一些注释:
第一个框中意思就是:BeanFactory是一个中央注册中心应用程序组件,并集中应用程序的配置
组件,不再需要单独的对象读取属性文件(也就是说我只需要从context中根据beanName啥的读取Bean实例即可,从各个配置源(如XML)中解析的工作就交给你们ApplicationContext了。
第二个框是说实现了BeanFactory的组件应该尽可能的按照顺序支持Bean的生命周期。
在context.png中描述了一个关键的类,DefaultListableBeanFactory
:
上面说了从配置源读取并解析Bean是context做的事情,那么context具体交给谁了呢?那就是beanDefinitionMap,既然是个Map,那我们就关心怎么PUT进去和怎么Get出来的。
从DefaultListableBeanFactory类的继承关系中可以看出一点问题:
BeanDefinitionRegistry,从名字上看是注册BeanDefinition的,具体看下里面的内容:
image.png这个接口也是提供了一些规范,例如注册,移除,获取,是否包含等功能,这样可以很方便的操作BeanDefinition。
三、总结
这一章的总结就到这,感觉自己想表达很多东西,但是又不知道怎么来组合下,只能顺着自己的思路来了,可能比较乱,但是后面的内容会好一点,多一点源码上的理解和实战,主体思路是这样的:
- 介绍一些基本的接口规范,自己最开始看的时候直接进入了一些复杂的实现,确实是看不懂.....如果先从接口看起,理解下Spring设计者的一些思路,后面会好理解很多,毕竟我们这次看源码的主要原因是想了解Spring的思路,之后再从Spring中学习一点设计和编码风格。
- Context结构
- 加载Bean
- 实例化Bean