Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而启动Spring就是为创建Bean对象做准备,所以我们先明白Spring到底是怎么去创建Bean的,也就是先弄明白Bean的生命周期。
Bean的生命周期就是指:在Spring中,一个Bean是如何生成的,如何销毁的?
Bean的生成过程
1. 生成BeanDefinition
Spring启动的时候会进行扫描,会先调用
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
拿到所指定的包路径下的所有文件资源(******.class文件)
然后会遍历每个Resource,为每个Resource生成一个MetadataReader对象,这个对象拥有三个功能:
- 获取对应的Resource资源
- 获取Resource对应的class的元数据信息,包括类的名字、是不是接口、是不是一个注解、是不是抽象类、有没有父类,父类的名字,所实现的所有接口的名字,内部类的类名等等。
- 获取Resource对应的class上的注解信息,当前类上有哪些注解,当前类中有哪些方法上有注解
在生成MetadataReader对象时,会利用ASM技术解析class文件,得到类的元数据集信息合注解信息,在这个过程中也会利用ClassLoader去加载注解类(ClassUtils.getDefaultClassLoader()所获得的类加载器),但是不会加载本类。
有了MetadataReader对象,就相当于有了当前类的所有信息,但是当前类并没有加载,也是可以理解的,真正在用到这个类的时候才加载。
然后利用MetadataReader对象生成一个ScannedGenericBeanDefinition对象,注意此时的BeanDefinition对象中的beanClass属性存储的是当前类的名字,而不是class对象。(beanClass属性的类型是Object,它即可以存储类的名字,也可以存储class对象)
2. 合并BeanDefinition
如果某个BeanDefinition存在父BeanDefinition,那么则要进行合并
3. 加载类
有了BeanDefinition之后,后续就会基于BeanDefinition去创建Bean,而创建Bean就必须实例化对象,而实例化就必须先加载当前BeanDefinition所对应的class,在AbstractAutowireCapableBeanFactory类的createBean()方法中,一开始就会调用:
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
这行代码就是去加载类,该方法是这么实现的:
if (mbd.hasBeanClass()) { return mbd.getBeanClass(); } if (System.getSecurityManager() != null) { return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); } else { return doResolveBeanClass(mbd, typesToMatch); }
public boolean hasBeanClass() { return (this.beanClass instanceof Class); }
如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载(doResolveBeanClass方法所做的事情)
会利用BeanFactory所设置的类加载器来加载类,如果没有设置,则默认使用ClassUtils.getDefaultClassLoader()所返回的类加载器来加载。
ClassUtils.getDefaultClassLoader()
- 优先获取当前线程中的ClassLoader
- 如果为空,则获取加载ClassUtils类的类加载器(正常情况下,就是AppClassLoader,但是如果是在Tomcat中运行,那么则会是Tomcat中为每个应用所创建的WebappClassLoader)
- 如果为空,那么则是bootstrap类加载器加载的ClassUtils类,那则获取系统类加载器进行加载
4. 实例化前
允许第三方可以不按照Spring的正常流程来创建一个Bean,可以利用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法来提前返回一个Bean对象,直接结束Bean的生命周期
5. 推断构造方法
单独讲
6. 实例化
构造方法反射得到一个实例
7. BeanDefinition的后置处理
for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } }
这里可以处理BeanDefinition,但是此时实例对象已经生成好了,所以修改beanClass已经没用了,但是可以修改PropertyValues,比如:
public class LubanMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor { public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { if (beanName.equals("userService")) { beanDefinition.setBeanClass(User.class); // 没用 beanDefinition.getPropertyValues().add("name","xxx"); } } }
8. 填充属性
单独讲
9. 执行Aware
- ((BeanNameAware) bean).setBeanName(beanName);
- ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
- ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
10. 初始化前
for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; }
11. 初始化
- ((InitializingBean) bean).afterPropertiesSet();
- 执行BeanDefinition中指定的初始化方法
12. 初始化后
for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; }
Bean的销毁过程
1. 容器关闭
2. 发布ContextClosedEvent事件
3. 调用LifecycleProcessor的onClose方法
4. 销毁单例Bean
- 找出所有DisposableBean(实现了DisposableBean接口的Bean)
- 遍历每个DisposableBean
- 找出依赖了当前DisposableBean的其他Bean,将这些Bean从单例池中移除掉
- 调用DisposableBean的destroy()方法
- 找到当前DisposableBean所包含的inner beans,将这些Bean从单例池中移除掉 (inner bean参考https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-inner-beans)
这里涉及到一个设计模式:适配器模式
在销毁时,Spring会找出实现了DisposableBean接口的Bean。
但是我们在定义一个Bean时,如果这个Bean实现了DisposableBean接口,或者实现了AutoCloseable接口,或者在BeanDefinition中指定了destroyMethodName,那么这个Bean都属于“DisposableBean”,这些Bean在容器关闭时都要调用相应的销毁方法。
所以,这里就需要进行适配,将实现了DisposableBean接口、或者AutoCloseable接口等适配成实现了DisposableBean接口,所以就用到了DisposableBeanAdapter。
会把实现了AutoCloseable接口的类封装成DisposableBeanAdapter,而DisposableBeanAdapter实现了DisposableBean接口。
相关推荐
Spring中Bean的生命周期和作用域及实现方式 Spring是一个非常流行的Java应用程序框架,它提供了一个灵活的机制来管理Bean的生命周期和作用域。Bean的生命周期和作用域是Spring框架中两个非常重要的概念,它们决定了...
"Spring中Bean的生命周期详解" Spring框架是当前Java EE开发中最流行的框架之一,Spring框架中Bean的生命周期是指从创建到销毁的整个过程。在这个过程中,Spring IOC容器对Bean的生命周期进行管理,使得开发者可以...
"Spring Bean 生命周期详解" Spring Bean 生命周期是 Spring 框架中的一个核心概念,了解 Spring Bean 的生命周期对我们了解整个 Spring 框架会有很大的帮助。本文将详细介绍 Spring Bean 生命周期的概念、生命周期...
在Spring框架中,在IOC容器中管理的Bean分为单例和原型两种,单例Bean在容器启动时就实例化,原型Bean则是每次从容器中请求时才会实例化。
Spring 中 Bean 生命周期回调方法详解 Spring 中 Bean 的生命周期回调方法是指在 Bean 的生命周期中, Spring 框架提供了多种方式来实现对 Bean 的生命周期的管理。这些回调方法可以在 Bean 的初始化、销毁等阶段被...
例如,可以使用 Spring 的 @Order 注解来指定 bean 的初始化顺序,也可以使用 Spring 的生命周期接口(如 InitializingBean)来控制 bean 的初始化顺序。 总结 控制 2 个 bean 的初始化顺序是一个常见的问题,本篇...
【Spring Bean的生命周期详解】 Spring Bean的生命周期是理解Spring框架工作原理的重要组成部分。Spring作为Java领域最广泛应用的轻量级框架,其管理Bean的方式对于优化应用程序的性能和可维护性至关重要。了解Bean...
Spring 框架系列(8)- Spring IOC 实现原理详解之 Bean 实例化(生命周期、循环依赖等) 本文主要研究 Spring 框架中 Bean 的实例化过程,包括 Bean 的生命周期和循环依赖问题的解决方案。在 Spring 框架中,Bean ...
Spring 配置使用之 Bean 生命周期详解是指在 Spring 框架中,Bean 从创建到销毁的整个过程。这个过程是非常重要的,因为它决定了 Bean 的生命周期和行为。 基本概念 在 Spring 中,Bean 的生命周期指的是 Bean 从...
Spring 中 bean 的作用域是指 Spring IoC 容器中 bean 的生命周期和实例化方式。bean 的作用域决定了 bean 的实例化和生命周期的管理方式。在 Spring 中,bean 的作用域可以分为五种:singleton、prototype、...
### Bean的生命周期详解 在Spring框架中,Bean的生命周期是一个重要的概念,它涉及到Bean的创建、初始化以及销毁等过程。了解这些过程对于更好地利用Spring框架的功能具有重要意义。 #### Bean的创建 Bean的创建...
值得注意的是,Prototype作用域下的Bean生命周期主要由客户端代码控制。Spring只负责初始化Bean,但不会管理其销毁过程。如果需要清理资源,通常需要手动实现。 #### 五、Request作用域 **Request**作用域下的Bean...
Spring Bean的初始化和销毁是Spring框架中一个非常重要的概念,它们都是Bean生命周期中不可或缺的一部分。在Spring框架中,我们可以使用多种方式来控制Bean的初始化和销毁,以下就Spring Bean的初始化和销毁进行详细...
在Spring框架中,Bean的实例化是其核心功能之一,用于管理对象的生命周期和依赖关系。本文将详细探讨Spring中bean实例化的三种主要方式:普通构造方法创建、静态工厂创建和实例工厂创建。 1. 普通构造方法创建: 这...
Spring通过Bean定义对象的生命周期、属性和依赖关系,使得对象的创建和管理变得简单。 2. **Spring的设计理念** Spring的核心理念是面向Bean的编程(BOP),强调通过配置管理对象间的依赖关系。Bean在Spring中...
总的来说,理解并掌握Spring框架中Bean的定义和生命周期对于Java Web开发至关重要。它不仅涉及到Bean的创建、初始化和销毁,还涉及到Bean间的依赖注入、生命周期管理以及各种扩展机制,这些都是构建可维护、可扩展的...