设计模式——自定义SpringIOC,BeanFactory接口分析
Spring IOC相关接口分析
1、BeanFactory解析
Spring中Bean的创建是典型的工厂模式,这一系列的Bean工厂,即IOC容器,为开发者管理对象之间的依赖关系提供了很多便利和基础服务,在Spring中有许多IOC容器的实现供用户选择,其相互关系如下图所示。
其中,BeanFactory作为最顶层的一个接口,定义了IOC容器的基本功能规范,BeanFactory有三个重要的子接口:ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory。但是从类图中我们可以发现最终的默认实现类是DefaultListableBeanFactory,它实现了所有的接口。
那么为何要定义这么多层次的接口呢?
每个接口都有它的使用场合,主要是为例区分在Spring内部操作过程中对象的传递和转化,对对象的数据访问所做的限制。
例如:
- ListableBeanFactory接口表示这些Bean可列表化。
- HierarchicalBeanFactory表示这些Bean是有继承关系的,也就是每个Bean可能有父Bean。
- AutowireCapableBeanFactory接口定义Bean的自动装配规则。
这三个接口共同定义了Bean的集合、Bean之间的关系及Bean行为。最基本的IOC容器接口时BeanFactory,来看一下它的源码:
1 | public interface BeanFactory { |
在BeanFactory里只对IOC容器的基本行为做了定义,根本不关心你的Bean是如何定义及怎样加载的。正如我们只关心能从工厂里得到什么产品,不关心工厂是怎么生产这些产品的。
BeanFactory有一个很重要的子接口,就是ApplicationContext接口,该接口主要来规范容器中的bean对象是非延时加载,即在创建容器对象的时候就对象bean进行初始化,并存储到一个容器中。
要知道工厂是如何产生对象的,我们需要看具体的IOC容器实现,Spring提供了许多IOC容器实现,比如:
- ClasspathXmlApplicationContext:根据类路径加载xml配置文件,并创建IOC容器对象。
- FileSystemXmlApplicationContext:根据系统路径加载xml配置文件,并创建IOC容器对象。
- AnnotationConfigApplicationContext:加载注解类配置,并创建IOC容器。
2、BeanDefinition解析
Spring IOC容器管理我们定义的各种Bean对象及其相互关系,而Bean对象在Spring实现中是以BeanDefinition来描述的,如下面配置文件。
1 | <bean id="userDao" class="com.itheima.dao.impl.userDaoImpl"></bean> |
其继承体系如下图所示。
3、BeanDefinitionReader解析
Bean的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证足够的灵活性,以应对可能的变化。Bean的解析主要就是对Spring配置文件的解析。这个解析过程主要通过BeanDefinitionReader来完成,看看Spring中的BeanDefinitionReader的类结构图,如下图所示。
看看BeanDefinitionReader接口定义的功能来理解它具体的作用:
1 | public interface BeanDefinitionReader { |
4、BeanDefinitionRegistry解析
BeanDefinitionReader用来解析bean定义,并封装BeanDefinition对象,而我们定义的配置文件中定义了很多bean标签,所以就有一个问题,解析的BeanDefinition对象存储到哪儿?答案就是BeanDefinition的注册中心,而该注册中心顶层接口就是BeanDefinitionRegistry。
1 | public interface BeanDefinitionRegistry extends AliasRegistry { |
继承结构图如下:
从上面类图可以看到BeanDefinitionRegistry接口的子实现了主要有以下几个:
DefaultListableBeanFactory
在该类中定义了如下代码,就是用来注册bean
1
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
SimpleBeanDefinitionRegistry
在该类中定义了如下代码,就是用来注册bean
1
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);
5、创建容器
ClassPathXmlApplicationContext对Bean配置资源的载入是从refresh()方法开始的。refresh()方法是一个模板方法,规定了IOC容器的启动流程,有些逻辑要交给其子类实现。它对Bean配置资源进行载入,ClassPathXmlApplicationContext通过调用其父类AbstractApplicationContext的refresh()方法启动整个IOC容器对Bean定义的载入过程。






