Spring

Spring

Bean 的生命周期

  • 通过 BeanDefinition 获取 Bean 的定义信息
  • 通过构造函数实例化 Bean
  • Bean 的依赖注入
  • 处理 Aware 接口
  • BeanPostProcessor - 前置方法
  • 初始化方法(InitializingBean, init-method)
  • BeanPostProcessor - 后置方法
  • 销毁 Bean

BeanDefinition 是 Spring 容器在进行实例化时, 会将 xml 配置的 <bean> 信息封装成一个 BeanDefinition 对象, Spring 根据它来创建 Bean 对象
image.png

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 简单的三步

  • 实例化: 对应方法 AbstractAutowireCapableBeanFactorycreateBeanInstance 方法
  • 属性注入: 对应方法 AbstractAutowireCapableBeanFactorypopulateBean 方法
  • 初始化: 对应方法 AbstractAutowireCapableBeanFactoryinitializeBean
    其实就是
  • 实例化, new 了一个对象
  • 属性注入: 为 new 的对象填充属性
  • 初始化: 执行 aware 接口中的方法, 完成 AOP 代理

Spring 三级缓存

  • singletonObjects 一级缓存: 存储创建好的单例 Bean
  • earlySingletonObjects 二级缓存: 完成实例化, 还未进行属性注入及初始化的对象
  • 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 Bean
  • BeanFactory 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/
作者
Dong Su
发布于
2024年5月28日
许可协议