我们都知道spring中最核心的就是容器的概念,而交于spring管理的对象称为bean对象。在spring中我们这次以xml配置bean的方式进行简单模拟spring创建bean的初始化过程。
1、首先我们先来一起研究一下一个xml文件中bean的结构。
我们可以看到一个bean是一个标签所扩住的。而每个bean标签中可能存在多个property标签去代表这个bean中引用的其他的bean对象的属性,表示引用关系。
我们假设想自己写一个简单的spring bean初始化的源码,我们该怎么写呢?
我们需要一些必要的元素:
- 首先我们需要一个承载xml中每个bean的一个类,我们将这个类起名为BeanDefinition。这个类我们承载一个bean标签。
- 然后我们定义一个承载property标签的类,即property类。
- 除此之外我们的property在一个bean中可能会有多个,因此我们再定义一个容器去存储多个property,即MutablePropertyValues类,这个类因为是一个容器,我们自然想到使用迭代器模式去实现。
- 定义完这诸多结构后,我们就该定义一个存储这多个beanDefinition的容器,即注册类:BeanDefinitionRegistry。因为bean定义的容器注册有多种场景 , 因此我们这里使用接口,同时我们提供一个SimpleBeanDefinitionRegistry , 即只实现bean定义的注册功能。
- 到这里我们就需要再建立一个解析bean定义的类了,这个类的功能主要有两个,即通过读取xml文件解析封装bean定义并注册到注册中心。另外一个功能就是获取注册中心的对象。
- 上面这些都准备好了之后,我们就可以编写我们的bean工厂了,我们定义一个接口BeanFactory,这是一个接口,其中定义了多种getBean的方法。BeanFactory的其中 一个子实现类即AbstractApplicationContext类。
- AbstractApplicationContext类是一个抽象类,实现了BeanFactory,在其中定义一个抽象方法refresh(),refresh方法做两件事,一件事是调用reader去解析xml封装bean定义,第二件事便是调用getBean()去初始化bean对象。getBean在的实现延迟到子类实现,使用了模板方法模式,子类即ApplicationContext类,在该子类中,我们在构造器中创建reader的子实现类对象,通过调用父类的refresh方法,进行bean定义的加载,与初始化,在子类中,我们实现bean对象的初始化,根据bean定义去创建对应的bean对象,并存储在父类的变量中,即实现每个bean定义只有一个bean对象的单例模式。