Spring篇

大家好我是小明,今天复习框架


文章目录

  • [1. Spring框架中的单例bean是线程安全的吗??](#1. Spring框架中的单例bean是线程安全的吗??)
  • [2. AOP(面向切面编程)&& Spring中的事务是如何实现的](#2. AOP(面向切面编程)&& Spring中的事务是如何实现的)
  • [3. Spring事务失效的场景有哪些?](#3. Spring事务失效的场景有哪些?)
  • [4. Spring的bean的生命周期](#4. Spring的bean的生命周期)
  • [5. Spring的循环引用](#5. Spring的循环引用)
  • [6. SpringMVC的执行流程](#6. SpringMVC的执行流程)
  • [7. Spring的自动配置原理(最高频的面试题之一)](#7. Spring的自动配置原理(最高频的面试题之一))

总体复习路线


1. Spring框架中的单例bean是线程安全的吗??

Spring框架中的bean是单例的吗?

答:的确是单例

Spring框架中的单例bean是线程安全的吗??

不是线程安全的

count是一定有线程安全问题的,但是比如注入的service成员变量是变不了的

Spring bean并没有可变的状态(比如说Service类和DAO类),所以说某种程度上说Spring的单例bean是线程安全的。


2. AOP(面向切面编程)&& Spring中的事务是如何实现的

在不修改原有业务代码的前提下,给程序的【指定方法】统一增加通用功能的技术,核心就是AOP。

常见AOP使用场景

  • 记录操作日志
  • 缓存处理

举个例子:

记录操作日志:使用AOP环绕通知+切点表达式,通过环绕通知获取请求方法的参数,获取到参数数之后,保存到数据库;

还有比如说java的redis这一套注解也是AOP还有MyBatis操作Mysql数据这个一套注解。

Spring中的事务是如何实现的??

本质就是通过AOP功能,对方法前后进行拦截,在执行方法之前开始事务,执行完目标方法后根据执行的情况进行事务的提交或者回滚。


3. Spring事务失效的场景有哪些?

  1. 异常的捕获处理

    异常捕获处理之后,事务处理以为没有报错,就不会回滚,执行到哪里就到哪里。

解决办法:可以将异常抛出,比如说,异常捕获以后new Exception

  1. 抛出检查异常

    解决办法:
  2. 非public方法导致事务失效

    原因:Spring为方法的创建代理,添加事务通知,前提条件都是该方法时public的

总结:

① 异常捕获处理,自己处理了异常,没有抛出,解决:手动抛出

② 抛出检查异常,配置 rollbackFor 属性为 Exception

③ 非 public 方法导致的事务失效,改为 public


4. Spring的bean的生命周期

这个死记就好

生命周期简约版

① 通过 BeanDefinition 获取 bean 的定义信息

② 调用构造函数实例化 bean

③ bean 的依赖注入

④ 处理 Aware 接口 (BeanNameAware、BeanFactoryAware、ApplicationContextAware)

⑤ Bean 的后置处理器 BeanPostProcessor - 前置

⑥ 初始化方法 (InitializingBean、init-method)

⑦ Bean 的后置处理器 BeanPostProcessor - 后置

详细版

Spring Bean的完整生命周期执行步骤如下,顺序固定:

① 通过 BeanDefinition 获取bean的定义信息:读取Bean的配置信息(比如@Component、@Bean),确定Bean的类型、作用域、依赖关系等;

② 调用构造函数实例化 bean:Spring根据BeanDefinition的信息,通过反射调用构造方法,创建Bean的实例对象(相当于new一个对象);

③ bean 的依赖注入:为Bean的属性赋值,完成依赖注入(比如@Autowired注入Mapper、Service),解决Bean之间的依赖关系;

④ 处理 Aware 接口 (BeanNameAware、BeanFactoryAware、ApplicationContextAware):让当前Bean获取Spring容器的核心资源,比如BeanNameAware拿到自身的bean名称,ApplicationContextAware拿到Spring上下文对象;

⑤ Bean 的后置处理器 BeanPostProcessor - 前置处理:在Bean初始化方法执行前,对Bean做自定义增强处理,无返回值;

⑥ 执行初始化方法 (InitializingBean接口的afterPropertiesSet方法、xml配置的init-method、@PostConstruct注解):Bean初始化的核心步骤,用来做资源初始化(比如初始化连接池、加载配置文件);

⑦ Bean 的后置处理器 BeanPostProcessor - 后置处理:在Bean初始化完成后做增强,Spring AOP的动态代理就是在这一步实现的 ,返回增强后的代理对象;

⑧ Bean进入就绪状态,开始对外提供服务:此时Bean已经完全创建完成,可以正常调用;

⑨ 容器关闭时执行销毁方法 (DisposableBean接口的destroy方法、xml配置的destroy-method、@PreDestroy注解):释放Bean占用的资源(比如关闭数据库连接、线程池)。


5. Spring的循环引用

循环引用: 类之间相互依赖注入

举个例子:


Spring框架是如何解决的??

三级缓存


那么是不是不需要三级缓存了呢??

假如说A是单例,那就不行了,那他怎么解决循环依赖问题;

这张图为什么要把代理对象放到二级缓存里面呢??

因为A是单例的,不能再次实例化一个代理对象;后面想使用就直接使用二级缓存的代理对象;

构造方法注入出现循环依赖

这种Spring解决不了,原因:用于bean的生命周期中构造函数是第一个执行的,Spring框架并不能解决构造函数的依赖注入

解决方案:

使用@Lazy进行懒加载,什么时候需要该对象在进行创建。


6. SpringMVC的执行流程

前提:前后端分离开发

执行流程图:

执行步骤:

  • 用户发送出请求到前端控制器 DispatcherServlet
  • DispatcherServlet 收到请求调用 HandlerMapping(处理器映射器)
  • HandlerMapping 找到具体的处理器,生成处理器对象及处理器拦截器 (如果有),再一起返回给 DispatcherServlet
  • DispatcherServlet 调用 HandlerAdapter(处理器适配器)
  • HandlerAdapter 经过适配调用具体的处理器(Handler/Controller)
  • 方法上添加了 @ResponseBody
  • 通过 HttpMessageConverter 来返回结果转换为 JSON 并响应

7. Spring的自动配置原理(最高频的面试题之一)

  1. 在 Spring Boot 项目中的引导类上有一个注解 @SpringBootApplication,这个注解是对三个注解进行了封装,分别是:
  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan
  1. 其中 @EnableAutoConfiguration 是实现自动化配置的核心注解。该注解通过 @Import 注解导入对应的配置选择器。

选择器内部就是读取了该项目和该项目引用的 Jar 包的的 classpath 路径下 META-INF/spring.factories 文件(这是boot2的文件名,boot3改为*.imports)中的所配置的类的全类名。

在这些配置类中所定义的 Bean 会根据条件注解所指定的条件来决定是否需要将其导入到 Spring 容器中。

这么解释呢?RedisTemplate这个类大家都熟悉,在springspring.factories 文件的全类名的代码是这样子的

引用依赖之后程序启动前会判断是否有RedisOperations这个类对应字节码,如果有执行下面代码,判断当前环境是否存在RedisTemplate这个bean,如果存在就不加载,没有执行下面代码返回RedisTemplate对象并注入Spring容器中。


好了今天就到这里

相关推荐
JaredYe2 小时前
node-plantuml-2:革命性的纯Node.js PlantUML渲染器,告别Java依赖!
java·开发语言·node.js·uml·plantuml·jre
IT 行者2 小时前
Spring Security 7 之 OIDC /connect/userinfo 端点解析:ID Token 与用户信息获取
linux·服务器·spring
hhzz2 小时前
Springboot项目中使用EasyPOI方式导出合同word文档
java·spring boot·后端·word·poi·easypoi
派大鑫wink2 小时前
【Day38】Spring 框架入门:IOC 容器与 DI 依赖注入
java·开发语言·html
爱丽_2 小时前
Spring Bean 管理与依赖注入实践
java·后端·spring
独自破碎E2 小时前
什么是Spring Bean?
java·后端·spring
手握风云-2 小时前
JavaEE 进阶第十期:Spring MVC - Web开发的“交通枢纽”(四)
前端·spring·java-ee
人道领域2 小时前
JavaWeb从入门到进阶(Maven的安装和在idea中的构建)
java·maven
XXOOXRT2 小时前
基于SpringBoot的留言板
java·spring boot·后端