1、BeanDefiniition的Resource定位
BeanDefinition的资源定位由ResourceLoader通过统一的Resource接口来完成,这个Resource对各种形式的BeanDefinition的使用提供了统一接口。对于这些BeanDefinition的存在形式,相信大家都不会感到陌生。比如说,在文件系统中的Bean定义信息可以使用FileSystemResource来进行抽象;在类路径中可以使用前面提到的ClassPathResource来使用,等等。这个过程类似于容器寻找数据的过程,就像用水桶装水先要把水找到一样。
2、BeanDefinition的载入和解析
载入过程把用户定义好的Bean表示成IoC容器内部的数据结构,而这个容器内部的数据结构就是BeanDefinition,下面可以看到这个数据结构的详细定义。总地说来,这个BeanDefinition实际上就是POJO对象在IoC容器中的抽象,这个BeanDefinition定义了一系列的数据来使得IoC容器能够方便地对POJO对象也就是Spring的Bean进行管理。即BeanDefinition就是Spring的领域对象。
refresh非常像重启容器,具体步骤如下图所示:
3、BeanDefinition在IoC容器中的注册
这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的,这个注册过程把载入过程中解析得到的BeanDefinition向IoC容器进行注册。可以看到,在IoC容器内部,是通过使用一个HashMap来持有这些BeanDefinition数据的。
值得注意的是,IoC容器和上下文的初始化一般不包含Bean依赖注入的实现。一般而言,依赖注入发生在应用第一次向容器通过getBean索取Bean时。但有一个例外值得注意,在使用IoC容器时有一个预实例化的配置,这个预实例化是可以配置的,具体来说可以通过在Bean定义信息中的lazyinit属性来设定;有了这个预实例化的特性,用户可以对容器初始化过程作一个微小的控制;从而改变这个被设置了lazyinit属性的Bean的依赖注入的发生,使得这个Bean的依赖注入在IoC容器初始化时就预先完成了。