1.Spring架构设计
Spring框架是一个分层架构,他包含一系列的功能要素,并被分为大约20个模块
2. 设计理念
Spring是面向Bean的编程(BOP:Bean Oriented Programming),Bean在Spring中才是真正的主角。Bean在Spring中作用就像Object对OOP的意义一样,没有对象的概念就像没有面向对象编程,Spring中没有Bean也就没有Spring存在的意义。Spring提供了IoC 容器通过配置文件或者注解的方式来管理对象之间的依赖关系。
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。
3. 核心组件介绍
Bean组件
Bean组件定义在Spring的org.springframework.beans包下,解决了以下几个问题:
这个包下的所有类主要解决了三件事:
- Bean的定义
- Bean的创建
- Bean的解析
Spring Bean的创建是典型的工厂模式,它的顶级接口是BeanFactory。
BeanFactory有三个子类:ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory。目的是为了区分Spring内部对象处理和转化的数据限制。
但是从图中可以发现最终的默认实现类是DefaultListableBeanFactory,它实现了所有的接口
Bean定义:BeanDefinition
这里的 BeanDefinition 就是我们所说的 Spring 的 Bean,我们自己定义的各个 Bean 其实会转换成一个个 BeanDefinition 存在于 Spring 的 BeanFactory 中
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
}
BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。
Context组件
Context在Spring的org.springframework.context包下
Context模块构建于Core和Beans模块基础之上,提供了一种类似于JNDI注册器的框架式的对象访问方法.Context模块继承了Beans的特性,为Spring核心提供了大量扩展,添加了对国际化(例如资源绑定)、事件传播、资源加载和对Context的透明创建的支持
ApplicationContext是Context的顶级父类
ApplicationContext 的子类主要包含两个方面:
- ConfigurableApplicationContext 表示该 Context 是可修改的,也就是在构建 Context 中用户可以动态添加或修改已有的配置信息
- WebApplicationContext 顾名思义,就是为 web 准备的 Context 他可以直接访问到 ServletContext,通常情况下,这个接口使用少
再往下分就是按照构建 Context 的文件类型,接着就是访问 Context 的方式。这样一级一级构成了完整的 Context 等级层次。
总体来说 ApplicationContext 必须要完成以下几件事:
- 标识一个应用环境
- 利用 BeanFactory 创建 Bean 对象
- 保存对象关系表
- 能够捕获各种事件
面试题:简述Spring后置处理器
后置处理器是一种拓展机制,贯穿Spring Bean的生命周期
后置处理器分为两类:
BeanFactory后置处理器:BeanFactoryPostProcessor
实现该接口,可以在spring的bean创建之前,修改bean的定义属性
public interface BeanFactoryPostProcessor {
/*
* 该接口只有一个方法postProcessBeanFactory,方法参数是ConfigurableListableBeanFactory,通过该
参数,可以获取BeanDefinition
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
Bean后置处理器:BeanPostProcessor
BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口
实现该接口,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些处理逻辑
public interface BeanPostProcessor {
//bean初始化方法调用前被调用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//bean初始化方法调用后被调用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
运行顺序
=Spring IOC容器实例化Bean= =调用BeanPostProcessor的postProcessBeforeInitialization方法= =调用bean实例的初始化方法= =调用BeanPostProcessor的postProcessAfterInitialization方法=
4. IOC流程图
5. Bean的生命周期
Bean 生命周期的整个执行过程描述如下。
1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
2)利用依赖注入完成 Bean 中所有属性值的配置注入。
3)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作
7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
10)如果在 中指定了该 Bean 的作用范围为 scope=“singleton”,则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 中指定了该 Bean 的作用范围为 scope=“prototype”,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法。
6. Spring源码环境构建
1. 自动化构建Gradle
引言:
从Sping5开始,官方就开始使用gradle来构建环境了
接下来,我们所有的环境都要基于gradle
1.1 什么是Gradle
Gradle是一个项目自动化构建工具。
是Apache的一个基于Ant 和Maven的软件,用于项目的依赖管理
项目的构建经历了三个时代:
Apache Ant(2000 年左右)
Maven(2004年)
Gradle(2012 年左右)
Spring(5.0开始) 等优秀的开源项目都将自己的项目从 Maven 迁移到了 Gradle
1.2 安装Gradle
-
Gradle下载地址:https://gradle.org/releases/
(注:需下载6.0以下版本,版本太高,会导致idea中编译时,部分spring组件无法下载,此处下载的是5.6.4版本,具体配置步骤自行百度)
2. 下载Spring源码
2.1 下载
下载地址(GitHub): https://github.com/spring-projects/spring-framework
注意:对于源码要进行 git clone 拉取(如果直接下载zip,会报如下错误)
2.2 源码环境编译
进入bin目录下,执行 gradlew.bat(建议命令行中执行)
3 源码导入IDEA
直接open project (idea 2020)
漫长的等待…
(注意:手动配置JDK及gradle)
构建完成后,模块会出现蓝色小点
3. 构建源码测试模块
3.1 创建新Module
3.2 添加依赖
打开 build.gradle
dependencies {
compile(project(':spring-context')) // 添加spring-context依赖
compile(project(':spring-aop')) // 添加spring-aop依赖
testCompile group: 'junit', name: 'junit', version: '4.12'
}
3.3 编写测试代码
- 编写TestBean
@Component
public class TestBean {
public void print(){
System.err.println("testBean method...");
System.err.println("spring源码环境构建完成...");
}
}
- 创建applicationContext.xml,配置TestBean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="testBean" class="com.xc.config.TestBean"/>
</beans>
- 编写测试类IOCTest
public class IOCTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TestBean testBean = (TestBean) applicationContext.getBean("testBean");
testBean.print();
}
}