Spring IOC知识点总结

IOC容器中的核心角色

BeanFactory

BeanFactory接口是Spring IOC中的一个核心接口,提供了IOC容器的基本实现,用于管理和创建Bean,即IOC容器是基于BeanFactory接口实现的。BeanFactory接口的主要功能有获取Bean、检索IOC容器中是否包含Bean、判断Bean是否是单例等。BeanFactotory主要负责Bean的加载、实例化、维护Bean之间的依赖关系、负责Bean的生命周期。
下面我们来看下BeanFactory接口的主要继承结构。
Spring IOC知识点总结

从上图我们可以看到BeanFactory接口下有三个子接口ListableBeanFactoryHierachicalBeanFactoryAutowireCapableBeanFactory。这三个子接口分别应用于不同的场景Listable可以获取多个Bean,最顶层的BeanFactory都是获取单个Bean;Hierachical主要用来处理BeanFactory的父子关系,可以获得BeanFactory的父工厂;AutowireCapable主要用来自动装配Bean的。

从图中我们发现BeanFactory经过一系列的继承最终由DefaultListableBeanFactory这个子类全部继承,即DefaultListableBeanFactory类拥有BeanFactory的全部功能,是BeanFactory的集大成者,在Spring IOC中也是由DefaultListableBeanFactory类来实现IOC容器。

BeanFactory和FactoryBean的区别

BeanFactory是一个工厂类,用于管理和创建Bean的工厂。
FactoryBean是一个Bean,也是一个接口。实现了该接口的类,通过容器获取Bean,返回的不是他们本身,而是接口getObject方法中生产的实例。例如当一个类ABean实现了FactoryBean,通过容器使用getBean(String beanName),即applicationContext.getBean(“aBean”),返回的不是aBean对象,而是aBean实现getObject中生成的实例。如果要返回它本身需要在beanName前面加上“&”,即applicationContext.getBean("&aBean")。

ApplicationContext

ApplicationContext接口继承了众多接口,为Spring的运行提供基本的功能支撑。这里我们主要讲它与BeanFactory之间的关系,前面我们讲到了BeanFactory,从BeanFactory的继承体系中我们可以看到AppicationContext接口继承了BeanFactoryListableBeanFactory接口和HierarchicalBeanFactory接口,从这里我们就可以只知道ApplicationContext就是一个BeanFactory,具有BeanFactory的所有功能。你可能想说ApplicatoinContext接口并没有继承AutowireCapableBeanFactory接口,这个不需要担心,在它的抽象实现类(AbstractRefreshableApplicationContext)中依赖了一个BefaultListableBeanFactory,这样ApplicationContext就具有了BeanFactory的全部功能。下面我们来看下ApplicationContext接口的继承结构,常用的类有ClassPathXmlApplicationContextFileSystemXmlApplicationContext 以及AnnotationConfigApplicationContext
Spring IOC知识点总结

BeanDefinition

Spring可以说是面向Bean编程,将对象以Bean的形式注入到Spring容器中,而每一个Bean(对象)的类型,依赖关系,字段等信息都不一样,那么怎么做到统一管理Bean呢?在Spring中就用到了BeanDefinition这个概念来实现对Bean的包装,从而使的Spring能够统一管理Bean。

BeanDefinition中记录了和Bean相关的所有信息,如是否是单例、作用范围、依赖关系、BeanName等。

从上图我们可以看到BeanDefinition主要继承了AttributeAccessor接口和BeanMetadataElement接口。
AttributeAccessor主要用来操作Bean的元数据。
BeanMetadataElement主要用来获取当前元素的配置源bean对象。
Spring IOC知识点总结

BeanWrapper

BeanWrapper是Bean的包装类,即在内部会保存Bean的实例,并提供其他一些扩展功能。同时,BeanWrapper接口还继承了PropertyAccessor, propertyEditorRegistry, TypeConverter、ConfigurablePropertyAccessor接口,所以它还提供了访问bean的属性值、属性编辑器注册、类型转换等功能。通过BeanWrapper,Spring IOC可以用统一的方式来访问Bean的属性。
Spring IOC知识点总结

Spring IOC容器的启动过程

Bean加载

Spring IOC知识点总结

1、ResourceLoad根据路径加载(xml)配置文件,并将配置文件转化成Resource对象。

2、BeanDefinitionReader将配置文件中的配置转换成Spring能够识别的BeanDefinition注册到BeanFactory中。

BeanDefinitionReader加载Bean的详细步骤(loadBeanDefinitionf方法)
1、DocumentLoader将Resource文件转化成Document对象。
2、BeanDefinitionDocumentReader解析Document对象,将配置文件中的配置解析成Spring可以识别的BeanDefinition。
3、通过BeanDefinitionRegistry将BeanDefinition注册到Spring的IOC容器中(默认是DefaultListableBeanFactory作为IOC容器)

Bean初始化

要注意的是虽然上面我们已经将Bean加载到IOC容器中,但是此时的Bean是没有初始化的。Bean的初始化实在getBean的时候执行。
Spring IOC知识点总结
1、根据BeanName去获取Bean实例,判断是否是单例Bean,是的话则从缓存中获取,没有再去创建,不是单例Bean则直接创建。

2、在创建Bean之前,先根据BeanName去我们的IOC容器中获取BeanDefinition。

3、根据BeanDefinition获取Bean所有的依赖关系,根据依赖关系,先创建被依赖的Bean。

4、被依赖的Bean创建好之后则是根据BeanDefinition创建Bean实例。

创建Bean实例的具体步骤:
1、根据BeanDefinition通过反射创建Bean的实例,注意此时的Bean还没有设置属性。
2、将创建好的Bean实例用BeanWrapper封装。
Definition通过反射创建Bean的实例,注意此时的Bean还没有设置属性。
2、将创建好的Bean实例用BeanWrapper封装。
3、根据BeanDefinition给Bean实例注入属性(即依赖注入)。