尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

【Spring框架学习(三)】:Spring Bean生命周期源码解析

【Spring框架学习(三)】:Spring Bean生命周期源码解析 Spring框架学习系列《Spring框架学习一从设计思想到核心架构全面认识Spring》《Spring框架学习二IOC核心原理解析为什么Autowired可以自动注入》《Spring框架学习三Spring Bean生命周期详解》《Spring框架学习四Spring AOP动态代理实现原理》《Spring框架学习五Spring MVC请求处理流程解析》《Spring框架学习六Spring事务实现原理》《Spring框架学习七Spring Boot自动配置原理》《Spring框架学习八Spring源码整体流程总结》一、前言在上一篇文章中我们学习了 Spring IOC 的核心原理。我们知道Spring 会通过 IOC 容器管理对象。一个普通 Java 类Service public class UserService { }经过 Spring 管理后就成为了一个 Bean。但是一个问题随之而来Spring 中的 Bean 到底是如何创建出来的从类被扫描到对象被使用中间经历了哪些过程例如Autowired private UserDao userDao;为什么 Spring 可以自动完成注入例如PostConstruct public void init(){ }为什么这个方法会自动执行这些问题都和 Bean 生命周期有关。本文将从源码流程和实际开发角度分析 Spring Bean 从创建到销毁的完整过程。二、什么是Bean生命周期Bean生命周期指的是一个 Bean 从被 Spring 创建到最终销毁所经历的整个过程。简单流程BeanDefinition ↓ 实例化 ↓ 属性注入 ↓ 初始化 ↓ 使用 ↓ 销毁Spring 对 Bean 的管理本质就是对这个生命周期进行控制。三、Bean生命周期整体流程Spring Bean 完整生命周期1. 实例化 Bean ↓ 2. 属性填充 ↓ 3. Aware接口回调 ↓ 4. BeanPostProcessor前置处理 ↓ 5. 初始化方法执行 ↓ 6. BeanPostProcessor后置处理 ↓ 7. Bean投入使用 ↓ 8. Bean销毁其中最重要的几个阶段实例化依赖注入初始化后置处理器四、第一步实例化Bean4.1 什么是实例化实例化就是创建对象。例如Java中UserService userService new UserService();Spring底层也是类似过程。4.2 Spring源码入口Bean创建核心类AbstractAutowireCapableBeanFactory核心方法createBean()调用doCreateBean()流程createBean() ↓ doCreateBean() ↓ createBeanInstance() ↓ 反射创建对象最终Spring通过反射创建Bean实例。五、第二步属性注入对象创建完成后Spring需要给对象中的属性赋值。例如Service public class UserService { Autowired private UserDao userDao; }此时UserService已经创建。但是userDao还是空。Spring接下来进行属性填充。5.1 属性注入源码核心方法populateBean()作用填充 Bean 属性。其中InstantiationAwareBeanPostProcessor会参与处理。而AutowiredAnnotationBeanPostProcessor就是其中一个重要实现。5.2 Autowired执行过程流程创建UserService ↓ 发现Autowired ↓ 寻找UserDao Bean ↓ 反射赋值 ↓ 完成依赖注入最终效果userService.userDao userDao;六、第三步Aware接口回调Spring提供了一系列Aware接口。作用让 Bean 获取 Spring 容器中的一些信息。常见接口接口作用BeanNameAware获取Bean名称BeanFactoryAware获取BeanFactoryApplicationContextAware获取ApplicationContext例如Component public class MyBean implements ApplicationContextAware { private ApplicationContext context; Override public void setApplicationContext( ApplicationContext applicationContext){ this.context applicationContext; } }执行过程中Spring会主动调用setApplicationContext()把容器对象传入。七、第四步BeanPostProcessor前置处理BeanPostProcessor中文Bean后置处理器。它是 Spring 提供的重要扩展机制。接口public interface BeanPostProcessor { Object postProcessBeforeInitialization( Object bean, String beanName); }作用在 Bean 初始化之前执行。例如Spring AOP就是基于这个机制实现的。执行流程创建Bean ↓ 属性注入 ↓ BeanPostProcessor前置处理 ↓ 初始化八、第五步初始化Bean初始化阶段Spring会执行各种初始化方法。主要有三种方式。8.1 PostConstruct最常见方式。代码Component public class UserService { PostConstruct public void init(){ System.out.println( 初始化完成); } }Bean创建完成后自动执行。8.2 InitializingBean接口实现public interface InitializingBean { void afterPropertiesSet(); }例如Component public class UserService implements InitializingBean { Override public void afterPropertiesSet(){ System.out.println(初始化); } }8.3 init-method配置初始化方法。例如Bean(initMethodinit) public UserService userService(){ return new UserService(); }九、第六步BeanPostProcessor后置处理初始化完成后Spring再次调用postProcessAfterInitialization()流程初始化 ↓ BeanPostProcessor后置处理 ↓ 返回最终Bean为什么需要这一步因为很多 Spring 功能依赖它。例如AOP代理对象创建例如Transactional public void save(){ }Spring不会直接返回原对象。而是原始Bean ↓ AOP增强 ↓ 代理Bean所以我们最终拿到的对象可能不是原始对象。十、单例Bean如何保存Spring默认Bean作用域singleton。也就是一个容器只有一个对象。Spring通过DefaultSingletonBeanRegistry保存。核心singletonObjects结构MapString,Object例如userService ↓ UserService对象以后再次获取直接从缓存返回。十一、Bean销毁阶段当 Spring 容器关闭时Bean会进入销毁阶段。例如关闭context.close();Spring会执行销毁方法。11.1 PreDestroy常用方式Component public class UserService { PreDestroy public void destroy(){ System.out.println( Bean销毁); } }11.2 DisposableBean实现public interface DisposableBean{ void destroy(); }十二、完整生命周期总结Spring Bean完整流程BeanDefinition ↓ 实例化 ↓ 属性注入 ↓ Aware接口 ↓ BeanPostProcessor前置 ↓ 初始化方法 ↓ BeanPostProcessor后置 ↓ 生成最终Bean ↓ 对象使用 ↓ 销毁十三、Bean生命周期中的核心扩展点Spring为什么设计这么复杂因为它需要提供扩展能力。其中最重要的是BeanPostProcessor它允许开发者在 Bean 创建过程中插入自己的逻辑。例如AOP自动代理注解处理事务增强很多 Spring 高级功能都建立在这个机制之上。十四、总结Spring Bean 生命周期本质就是Spring 如何控制一个对象从出生到消失。核心过程创建对象 ↓ 注入依赖 ↓ 执行初始化 ↓ 增强处理 ↓ 投入使用 ↓ 销毁资源理解 Bean 生命周期后就能真正理解为什么Autowired可以自动注入为什么PostConstruct会自动执行为什么Transactional需要代理为什么Spring可以扩展各种功能下一篇文章将继续深入《Spring框架学习四Spring AOP动态代理实现原理》从代理对象创建、JDK动态代理、CGLIB代理三个方面分析 Spring 如何实现面向切面编程。
返回列表