Spring核心组件原理解析
本文并不是博主原创的,在博主学习Spring底层原理时,看到本篇文章感觉收益颇丰,读了好几遍,每一遍都有不同的体会,所以想通过博客记录一下。
若有侵权立删。
Spring 的核心
任何实际的应用程序都是由很多组件组成的,每个组件负责整个应用功能的一部分,这些组件需要与其他的应用元素进行协调以完成自己的任务。当应用程序运行时,需要以某种方式创建并引入这些组件。
Spring Framework 总共有十几个组件,但真正核心的组件只有三个:Spring Core,Spring Context 和 Spring Bean,它们奠定了 Spring 的基础并撑起了 Spring 的框架结构。Spring 的其它功能特性例如 Web、AOP、JDBC 等都是在其基础上发展实现的。
Spring之中最重要的当属Bean了,Spring实际上就是面向Bean的编程,Bean对于Spring的意义就好比Object对于OOP的意义一样。那么,三个核心组件之间是如何协同工作的呢?如果把Bean比作一场演出中的演员,那么Context就是这场演出的舞台,Core就是演出的道具,至于演出的节目,就是Spring的一系列特色功能了。
我们知道Bean包裹的是Object,而Object中必然有数据,Context就是给这些数据提供生存环境,发现每个Bean之间的关系,为他们建立并维护好这种关系。这样来说,Context就是一个Bean关系的集合,这个关系集合就是我们所说的IOC容器。那么Core又有什么作用呢?Core就是发现、建立和维护每个Bean之间的关系所需的一系列工具,就是我们经常说的Util。
Bean 组件
Bean组件在Spring的org.springframework.beans包下,主要完成了Bean的创建、Bean的定义以及Bean的解析三件事。
SpringBean的创建是典型的工厂模式,其工厂的继承层次关系如图所示:
Spring 使用工厂模式来管理程序中使用的对象(Bean),Bean 工厂最上层的接口为 BeanFactory,简单来看,工厂就是根据需要返回相应的 Bean 实例。
public interface BeanFactory {
//...
Object getBean(String name);
}
在工厂模式中,在工厂的实现类中生成 Bean 返回给调用客户端,这就要求客户端提供生成自己所需类实例的工厂类,增加客户负担。Spring 结合控制反转和依赖注入为客户端提供所需的实例,简化了客户端的操作。具体的实现方式大致如下。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>;
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition){
//...
}
}
beanDefinitionMap 作为具体的 Bean 容器,Spring 创建的对象实例保存其中。客户端需要时,使用工厂的 getBean 方法去试图得到相应的实例,如果实例已存在,则返回该实例;如果实例不存在,则首先产生相应实例并通过 registerBeanDefinition 方法将其保存在 beanDefinitionMap 中(Lazy Initialization),然后返回该实例给客户端。
beanDefinitionMap 并不直接保存实例本身,而是将实例封装在 BeanDefinition 对象后进行保存。BeanDefinition 包含了实例的所有信息,其简化版的定义如下。
public class BeanDefinition {
private Object bean;
private Class<?> beanClass;
private String beanClassName;
// Bean 属性字段的初始化值