Spring源码系列-Spring框架简介

Spring 整体架构

Spring 的架构图如下所示:

spring基础架构

在 Spring 框架中,容器是核心部分,容器主要由以下几部分构成:spring-core spring-beans spring-context spring-context-support spring-expression 其中 spring-core 和 spring-brans 是构成Spring框架的基础,包括了IOC和DI的特性。 spring-context 负责容器中beans创建和管理。spring-context-support 负责集成第三方的包进入到框架中。spring-expression 是一组在运行时可以查询和操纵对象的表达式。

Spring 的依赖注入

提到Spring容器,就不得不提到IOC(控制反转) 和 DI(依赖注入),其实 IOC 和 DI描述的是同一个概念。依赖注入是指一个对象定义的依赖只通过构造函数参数或者setter方法来设置,容器在创建这个对象的时候会将该对象依赖的对象都注入进来。这个过程也称之为控制反转。对象本身可以通过构造对象或者 Service Locator 模式来实例化依赖。

这个概念这样看起来还是太过于抽象了,那么来看一个具体的例子。 原来的开发模式:

1
2
3
4
5
6
7
8
9
public class Foo {

private SpringIoc springIoc;


public Foo() {
this.springIoc = new SpringIoc();
}
}

依赖注入的模式是这样的:

1
2
3
4
5
6
7
8
9
public class Foo {

private SpringIoc springIoc;


public Foo() {
this.springIoc = new SpringIoc();
}
}

完了?完了。看起来这是在逗你吧。但是实际上,依赖注入干的就是这件事,依赖注入的核心是每个对象都不要去控制自己的依赖,所有的依赖都通过外部注入进来。那有人就说那这件事没有 Spring 也可以干这件事呀, 如下:

1
2
3
4
5
6
7
public class BarMain {

public static void main(String[] args) {
SpringIoc springIoc = new SpringIoc();
Bar bar = new Bar(springIoc);
}
}

但是需要注意的是,在这个代码中。还是存在需要手动去新建对象的情况,也就是说,问题根本没有被解决。这个时候,Spring 容器的出现就是为了解决这个问题的。Spring容器的出现就是为了干掉这个手动生成对象的操作。

Spring 容器的核心思想是所有的bean及其依赖都不需要手动去生成,都只需要通过Spring 容器来统一管理。需要实例化的时候直吴容器里面取就行了。Spring 容器这么强大,那么Spring容器到底是什么东西呢?

可以看出来,容器就是Spring框架提供用来生成和管理bean的机制。所有被容器管理的java对象都称之为 bean,bean之间的关系是通过配置的元数据来决定的,容器也是通过元数据来创建bean的。Spring容器与Java类和配置文件有很大的关系。一句话总结就是Spring容器可以根据提供的配置文件来维护bean及其依赖关系。

容器的初始化需要加载一个配置,通过这个配置才能确定容器中bean的生成和管理方式。容器的配置方式可以有多种:

  • xml配置
  • 基于注解的配置
  • 基于java的配置

这些配置方式都不是独立的,都可以结合起来使用,比如xml配置就经常与基于注解的配置方式结合起来使用。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {

public static void main(String[] args) {

BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-ioc.xml").getBeanFactory();
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-ioc.xml");


SpringIoc springIocFromBeanFactory = (SpringIoc) beanFactory.getBean("springIoc");
SpringIoc springIocFromApplicationContext = (SpringIoc) applicationContext.getBean("springIoc");

springIocFromBeanFactory.hellIoc();
springIocFromApplicationContext.hellIoc();
}
}

通常获取 ApplicationContext 对象来作为访问容器的接口。通过 ApplicationContext来获取 bean(当然实际的使用当中不会这么用)。 在容器初始化的过程中,容器会根据配置文件将大部分bean也实例化(设置了延迟加载的bean不会再启动阶段就初始化)。一个基于Spring的应用也算是启动起来了。 这些基本就是Spring框架最为核心的内容了,其他的Spring 模块都是在容器的基础之上构建出来的。