Spring容器的实现

1. 概念

        Spring容器有两个重要的概念-IOC(控制反转)和DI(依赖注入)。IOC和DI对学习Spring的人总感觉模糊不清以至于难以理解。因此在进行Spring容器实现的介绍之前,先通俗的了解下IOC和DI的相关知识。

IOC(控制反转)

        IOC(Inversion of Control)-控制反转,即指将原本由开发人员来控制对象的实例化来交给Spring容器来进行实例化,开发人员只需要进行简单的配置即好,Spring容器(这里指BeanFactory和ApplicationContext)会在合适的时机对配置的信息进行实例化。因此此处“控制反转”指的是对象的实例化控制反转给了Spring容器进行处理。

DI(依赖注入)

        DI(Dependency Injection)-依赖注入,即指原本由开发人员选择在某时通过构造参数或setter属性注入的方式向来设置对象的属性改为由Spring容器选择在何时的时机根据配置来进行属性的设置。
这样做的好处便是:提升了组件的重用频率,只需要配置一次,可以设置到多个对象中。

Spring容器的继承关系

BeanFactory继承关系图

BeanFactory继承关系图

        BeanFactory是Spring容器的最顶层接口,提供了Spring容器的最基本方法;XmlBeanFactory是BeanFactory的最终实现,不过在Spring5.x版本中被标记为过时了。上述图片中间的一列和右边的一列,暂时不考虑,他们提供了注册Bean实例和BeanDefinetion信息的相关接口和方法。在上述继承关系图中,我们重点关注BeanFactory、ListableBeanFactory、ConfigurableBeanFactory、AbstractBeanFactory和DefaultListableBeanFactory,接下来会详细讲解上述类的作用以及在后边的章节中会讲到一个Bean从配置到注入到Spring容器中的实现。

BeanFactory详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public interface BeanFactory {

//该属性针对于FactoryBean
String FACTORY_BEAN_PREFIX = "&";

//通过Bean名称(Id/name/alias)获取Bean的实例信息
Object getBean(String name) throws BeansException;

//通过Bean名称和类型获取Bean的实例信息
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
//根据Bean名称和构造参数的实参获取Bean的实例信息
Object getBean(String name, Object... args) throws BeansException;

//根据类型获取Bean实例信息
<T> T getBean(Class<T> requiredType) throws BeansException;

//根据类型和构造参数的实参获取Bean实例信息
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
//是不是包含该名称的Bean实例
boolean containsBean(String name);
//判断该Bean是否是单例模式
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

//判断该Bean是否是原型模式
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

//获取该名称Bean的所有别名
String[] getAliases(String name);
}

ApplicationContext继承关系图