一:Spring的主要工作
简单来说,Spring的工作主要有两点:1.明确哪些类需要Spring容器来创建和管理对象?(定义Bean实例)2.这些对象之间有什么关系?(定义依赖)。
1:Spring需要创建和管理哪些类的对象,Spring提供了三种主要的“语言”或“格式”来让你编写这份蓝图:XML、注解或Java部署。
XML、注解或Java配置类这三个文件分别存储什么内容,作用是什么?
Spring 定义 Bean 及其依赖关系的三种主要方式。它们本质上目的相同:就是XML、注解和 Java 设置告诉 Spring IoC 容器如何创建、组装和管理应用程序中的对象(Bean)。
一个就是Spring IoC容器管理Bean的全过程是一个精密的、可高度扩展的生命周期流程。它不仅仅是一个“工厂”,而完整的Bean生命周期管理者。其核心思想是控制反转(IoC) 和依赖注入(DI),将对象的创建、依赖组装、初始化、销毁等控制权从应用程序代码中反转到了容器中,使得代码更加松散耦合、易于测试和维护。
二:Bean的生命周期
容器启动与初始化
什么?就是1.容器
Spring 容器的具体表现就是一系列接口和类,最主要的有两个:
1.BeanFactory:这是容器的最基本接口,供应了基础的依赖注入功能。对于轻量级应用来说它已经足够,但它通常是面向框架内部使用的。
2.ApplicationContext: 这是BeanFactory的子接口,是更“强大”和“高级”的容器。除了提供依赖注入功能,它还集成了许多企业级作用,如:事件发布与监听(ApplicationEventPublisher),资源加载,AOP 功能的集成。因此,在绝大多数情况下,我们所说的“Spring 容器”指的就是ApplicationContext的具体建立,例如AnnotationConfigApplicationContext 或 ClassPathXmlApplicationContext
Spring 容器的底层实现非常复杂,但其核心工作流程允许简化为以下几个关键步骤(也就是Bean的生命周期):
1.加载与解析部署元数据:元信息指的是,描述数据的数据,比如说类名,属性之类的,具体数据存储在内存中,容器启动时,第一要读取你提供的“图纸”,即配置元数据,来了解需要管理哪些 Bean 以及它们之间的依赖关系)
方式:可以是 XML 文件、Java 注解(如@Component, @Autowired)或 Java 部署类(用@Configuration 标注的类过程:容器使用相应的“读取器”(如XmlBeanDefinitionReader 或 AnnotatedBeanDefinitionReader)来解析这些配置(以纯文本的方式解析,没有用到反射)这一步主要生成相应的beandefinition对象并存入注册表中。
2.实例化 BeanDefinition:解析配置后,容器并不会立即创建 Bean 对象,而是将每个<bean>标签或每个被@Component标注的类,解析成一个BeanDefinition 对象。BeanDefinition是什么?它是 Spring 框架中一个非常重要的接口,它的实例对象包含了创建一个 Bean 所需要的所有元信息,例如:Bean 的类名(Class),原型 Prototype就是Bean 的作用域(是单例 Singleton 还,是否延迟初始化(Lazy-init,初始化方法和销毁方法的名字,构造器参数和属性值(用于依赖注入)可以把它理解为 Bean 的“配方”或“蓝图”。此时,BeanDefinition被注册到一个巨大的BeanDefinitionRegistry一个 Map)中。就是(本质上
3.Bean 的实例化与依赖注入(核心中的核心):容器工作的核心阶段,通常被称为就是这Bean 的生命周期。它大致包括以下过程:1.实例化(Instantiate): 容器检查“花名册”(BeanDefinition),根据其中的beanClass 信息,通常依据Java反射(Class.newInstance()或构造器)来创建目标Bean的实例。这就是为什么Spring要求Bean有一个默认无参构造器(除非你指定了其他构造器),
依赖注入(DI): 这是最核心的一步。容器检查刚创建好的Bean实例,查看其BeanDefinition中的依赖关系(经过反射分析字段上的@Autowired或XML中定义的<property>.对于每个需要注入的依赖,容器会递归地先去获取(getBean())那个被依赖的Bean。如果那个Bean不存在,就先创建它.获取到依赖的Bean实例后,容器通过反射(Field.set()或Method.invoke())将依赖设置到目标Bean的属性/字段中.生命周期回调(Lifecycle Callbacks):在注入完成后,容器会检查Bean是否建立了像InitializingBean这样的接口,然后调用afterPropertiesSet()方法。这相当于给Bean一个信号:“你的所有依赖都注入完毕了,现在你许可进行一些初始化工作了”这一步是“依赖注入”的具体实现,其核心技术是反射(Reflection)和递归。容器主动地将依赖关系“注入”到对象中,而不是对象自己去查找。
4.Aware接口回调:如果 Bean 实现了BeanNameAware 等 Aware 接口,容器会调用相应的回调方法,将容器本身或Bean的名字等“注入”给Bean。这让Bean能感知到容器的存在。
5.BeanPostProcessor 前置处理:BeanPostProcessor是Spring献出的强大扩展点。容器会遍历所有已注册的BeanPostProcessor,并调用其 postProcessBeforeInitialization()方法。开发者可以在这里对Bean进行包装或修改。
6.初始化回调 (Initialization):调用初始化方法,如实现了InitializingBean接口或自定义的init-method。
7.BeanPostProcessor 后置处理:执行BeanPostProcessor的后置处理器,可能在这里产生代理对象。
8.销毁回调 (Destruction):最后是销毁bean。
管理和使用:经过以上所有步骤后,一个完全可用的Bean就诞生了。对于单例(Singleton)Bean,它会被存入Spring容器的一级缓存singletonObjects 中。当应用程序通过ctx.getBean(...) 或 @Autowired请求Bean时,容器会首先从这个缓存池中查找,直接返回已经完全初始化好的Bean实例。