Spring
Spring
Bean 的生命周期
- 通过 BeanDefinition 获取 Bean 的定义信息
- 通过构造函数实例化 Bean
- Bean 的依赖注入
- 处理 Aware 接口
- BeanPostProcessor - 前置方法
- 初始化方法(InitializingBean, init-method)
- BeanPostProcessor - 后置方法
- 销毁 Bean
BeanDefinition 是 Spring 容器在进行实例化时, 会将 xml 配置的 <bean>
信息封装成一个 BeanDefinition 对象, Spring 根据它来创建 Bean 对象
Aware 接口有什么用
- 通过实现特定的 Aware 接口, bean 可以获得对 Spring 容器的某些部分(如配置文件, 文件资源, 环境属性等) 的访问权
- ApplicationContextAware: 允许一个 bean 获得对 ApplicationContext 的访问, 意味着该 bean 可以访问 Spring 容器的所有配置信息的定义
- BeanNameAware: 它会在创建过程中接收到自己在容器中的名称
- BeanFactoryAware: Bean 可以直接访问到它所在的 BeanFactory, 从而允许请求其他 Bean 等操作
- 实现这些接口可以让不是在 Spring 的环境下, 获取 Spring 的 Bean, 例如通过 BeanFactory
InitializingBean 有什么作用
- 用于在初始化方法完成后执行自定义初始化逻辑
- 当一个 Bean 实现了 InitializingBean 接口时, Spring 容器在初始化Bean 并完成所有属性设置后会调用
afterPropertiesSet()
方法来执行额外初始化操作
Spring 出现循环依赖
- 循环依赖是指两个或多个 Bean 相互依赖, A 依赖于 B, B 依赖于 A
构造器注入循环依赖能解决吗
- 如果 A 和 B 都用构造器注入不行, 因为在创建 Bean 实例时需要调用构造函数创建 Bean
- 但是一个使用 Setter 注入, 一个使用构造器注入需要分情况考虑
- A 用 Setter 注入 B, B 用构造器注入 A, 可以解决循环依赖
- A 用构造器注入 B, B 用 Setter 注入 A, 不可以解决
- 因为 Spring 在创建 Bean 的时候默认是按照自然排序进行创建, A 会优先于 B 创建
Spring 创建 Bean 简单的三步
- 实例化: 对应方法
AbstractAutowireCapableBeanFactory
的createBeanInstance
方法 - 属性注入: 对应方法
AbstractAutowireCapableBeanFactory
的populateBean
方法 - 初始化: 对应方法
AbstractAutowireCapableBeanFactory
的initializeBean
其实就是 - 实例化, new 了一个对象
- 属性注入: 为 new 的对象填充属性
- 初始化: 执行 aware 接口中的方法, 完成 AOP 代理
Spring 三级缓存
singletonObjects
一级缓存: 存储创建好的单例 BeanearlySingletonObjects
二级缓存: 完成实例化, 还未进行属性注入及初始化的对象singletonFactories
三级缓存: 提前暴露一个单例工厂, 二级缓存中存储的就是从这个工厂中获取的对象
SpringMVC 的执行流程
- 用户发送请求到前端控制器 DispatchServlet
- DispatchServlet 收到请求, 调用 HandlerMapper
- HandlerMapper 找到具体的处理器, 生成处理器对象及处理器拦截器(如果有) 一起返回 DispatchServlet
- DispatchServlet 调用 HandlerAdapter(处理器适配器)
- HandlerAdapter 调用具体的 Controller
SpringBoot 自动装配原理 or 启动流程
- 在 SpringBoot 启动类上有一个
@SpringBootApplication
注解, 其中封装了三个注解@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
- 其中
@EnableAutoConfiguration
是实现自动配置的核心注解, 该注解通过@Import
注解导入对应的配置选择器类1
@Import({AutoConfigurationImportSelector.class})
- 配置选择器类内部读取该项目和该项目引用 jar 包的 classpath 路径下的 META-INF/spring.factories 文件, 该文件里有所需要加载的类的全限定类名, 会根据 bean 的条件注解决定是否将其导入 Spring 容器中
- 条件注解有像
@ConditionalOnClass
这样的注解, 表示有对应的 class 文件, 才加载
- 条件注解有像
SpringBoot 依赖管理
- 继承了
spring-boot-starter-parent
其又继承了spring-boot-dependencies
内部定义了很多依赖
spring-boot-starter 跟 spring-boot-starter-web 有什么区别
spring-boot-starter
是许多其他 Starter 的基础依赖, 但不包含任何特定的功能模块, 它包含以下内容- Spring Core
- Spring Context
- Spring AOP
spring-boot-starter-web
是专门用于构建 Web 应用的 Starter 依赖, 能处理 HTTP 请求, 它里面包含spring-boot-starter
- Spring Web
- Spring MVC
- Jackson
- Tomcat
Spring 常用的类
ApplicationContext
Spring 容器接口, 负责创建和管理 Spring BeanBeanFactory
Spring 容器, 提供 Bean 的基础管理BeanDefinition
InitializingBean
- 一些 Aware 接口
Spring 自动注入原理
- 使用反射机制将依赖注入到 Bean 中
- 构造器注入
- Setter 方法注入
- 字段注入
get 和 post 有什么区别
- get 参数拼接在 Url 后面, post 参数在请求体里, 相对安全
- 数据大小限制, get 受到 Url 长度的限制, post 理论上没有大小限制
- 幂等性, get 是幂等的, post 是非幂等的
Spring
http://showyoubug.cn/2024/05/28/Spring/