今天你学习了吗?
你竟然没学?
你这个年纪怎么敢天天都在玩呀?
前言
本文所整理的内容,参考于 某站 搜索 八股文 的第一个视频的内容,那个视频全部跟完需要花整整一天,为了节省时间,笔者做了一个快速整理,方便查阅。
关于Spring 和Springboot的八股知识点,思维导图如下。
(笔者有一个关于 Spring 和 Springboot 的专栏,欢迎大家订阅)
正文
一. Spring
1. Bean是线程安全的吗
Spring 中的Bean 有两种作用范围。
- Singleton 。Bean 在Ioc容器中只有一个实例;
- Prototype 。Bean 在Ioc容器中可以有多个。
如果是Singleton 的Bean ,那么Bean不是线程安全的。
2. 什么是AOP
AOP 就是面向切面编程,用于将与业务无关,但是却对多个Bean 产生影响的公共逻辑抽取并封装成一个可重用的模块,该模块称为切面,好处如下。
- 减少重复代码;
- 非业务逻辑与业务代码解耦;
- 提高代码可维护性。
3. AOP是怎么实现的
AOP 中的切面主要由切点 和通知组成,其中。
- 切点决定通知逻辑对在哪里生效 。比如切点是一个@RequestMapping 注解,那么对应的通知的逻辑就会对所有由@RequestMapping注解修饰的方法生效;
- 通知决定要做什么。通知其实就决定我们的切面最终要做的行为是什么。
那么如果一个Bean 有方法被切面切到了,那么这个Bean会经过下面这样的过程。
- Bean 创建出来后会在 Bean 后置处理器中被生成动态代理对象 。这里的动态代理可以是JDK 动态代理,也可以是CGLIB动态代理;
- 为 Bean 中被切面切的方法创建通知链并拦截方法调用 。打个比方,有一个Bean ,其method() 方法被两个切面给切了,那么这两个切面对应的通知会组成通知链,然后再将通知链封装成方法拦截器链,拦截的目标方法就是method() 方法,从而调用method() 方法时就可以执行到通知的逻辑。
AOP的详细实现,可以阅读一下下面两篇文章。
详细分析Spring的AOP源码上篇
详细分析Spring的AOP源码下篇
4. 事务原理
这里说的事务,指的是基于@Transactional 注解的声明式事务。
Spring 中实现事务,其实本质就是通过AOP 来实现的,@Transactional 注解修饰的方法执行前后,Spring的事务管理器会帮我们进行事务的一系列操作。
Spring的事务的具体实现机制,展开讲的话内容太多,感兴趣可以参考下面这篇文章。
(有人反馈说太催眠了,所以上面这篇文章建议只看总结部分)
5. 事务失效
事务失效分两大类来讨论。
第一类 就是@Transactional 注解没起作用。因为使用@Transactional 注解是基于AOP 来实现的,所以AOP 会失效的情况,事务就会失效,比如从Bean 的一个没有由@Transactional 注解修饰的方法调用到Bean 的一个由@Transactional 注解修饰的方法,此时这个由@Transactional注解修饰的方法是不会生效事务的。
第二类 就是@Transactional 注解起作用了但是异常没抛对。这种情况多是@Transactional注解上指定的回滚异常和实际抛出的异常不匹配,导致应该回滚的场景却没有回滚。
6. Bean的生命周期
一图流。
7. 循环依赖
结合下述流程图理解循环依赖。
至于一级缓存 ,二级缓存 和三级缓存 的作用,请直接去看一文彻底明白Spring的循环依赖的第四五六节的内容,这里不再重复贴出。
请注意 ,在Springboot 的2.6.0 版本开始,默认是不支持循环依赖的,如果存在循环依赖会启动报错。
二. SpringMVC
1. SpringMVC执行流程
SpringMVC的执行流程图如下。
在SpringMVC 中,有两个最为重要的类,其一是RequestMappingHandlerMapping ,其二是RequestMappingHandlerAdapter。
RequestMappingHandlerMapping 的作用是将Controller 类里面所有的@RequestMapping 注解解析并生成RequestMappingInfo ,然后建立起Handler (Controller 类 ),HandlerMethod (Controller 类里被 @RequestMapping 注解修饰的方法 )和RequestMappingInfo 的映射关系,那么在请求到来时就会根据Request 去匹配RequestMappingInfo ,进而就得到对应的HandlerMethod。
RequestMappingHandlerAdapter 的作用有三部分,首先在执行HandlerMethod 之前会使用参数解析器从Request 中获取执行HandlerMethod 需要的参数,然后基于反射执行HandlerMethod ,最后使用返回值处理器将HandlerMethod的返回值写入响应体中。
关于SpringMVC的详细执行流程,可以阅读下面两篇文章。
详解SpringMVC-RequestMappingHandlerMapping
详解SpringMVC-RequestMappingHandlerAdapter
三. Springboot
1. Springboot自动装配原理
Springboot 项目的启动类需要由@SpringBootApplication注解修饰,该注解复合了如下三个注解。
- @SpringBootConfiguration 。表明Springboot启动类是一个配置类;
- @ComponentScan 。会将指定路径下的被特定注解修饰的类加载为Spring 中的Bean ,这些特定注解为@Component ,@Controller ,@Service ,@Repository 和@Configuration注解;
- @EnableAutoConfiguration 。用于开启Springboot的自动装配。
所以Springboot 自动装配是基于@EnableAutoConfiguration注解,该注解功能由如下两部分实现。
其一是@AutoConfigurationPackage 。@AutoConfigurationPackage 注解作用在Springboot 启动类上,会向Spring 容器注册一个类型为AutoConfigurationPackages.BasePackages 的Bean ,这个Bean 中保存了Springboot 启动类的包路径,后续Springboot 就会扫描这个包路径下由@Component ,@Controller ,@Service ,@Repository 和@Configuration注解修饰的类。
其二是@Import (AutoConfigurationImportSelector.class)。这个作用原理用下图进行示意。
也就是通过@Import 注解导入了AutoConfigurationImportSelector ,后续就会调用到SpringFactoriesLoader 去扫描并加载该项目和该项目引用的Jar 包的classpath 路径下META-INF/spring.factories 文件中配置的所有的EnableAutoConfiguration。
关于Springboot的自动装配,可以参考下面这篇文章。
除此之外,和自动装配比较相关的内容是Springboot 下如何自定义Starter包,可以参考下面这篇文章。
详解Spring的SPI机制和自定义Springboot的Starter包
总结不易,如果本文对你有帮助,烦请点赞,收藏加关注,谢谢帅气漂亮的你。