SSM拷打第二讲!!!

7. Spring中的循环引用?

复制代码
是什么->能解决的是什么->三级缓存

Spring 的循环依赖就是 Bean 之间互相依赖,比如 A 依赖 B,B 又依赖 A。

Spring 能解决的主要是单例 Bean 的属性注入循环依赖。它的核心思路是:A 实例化之后,还没完成属性填充和初始化,就先把 A 的早期引用暴露出来;这时 B 创建时需要 A,就可以先拿到这个早期引用,等 B 创建完再回头完成 A 的注入。

三级缓存里,一级缓存放完整 Bean,二级缓存放早期 Bean,三级缓存放 ObjectFactory。三级缓存的意义主要是为了在有 AOP 的情况下,能提前拿到代理对象,避免注入原始对象。

但构造器循环依赖和原型 Bean 循环依赖解决不了,因为它们没法像单例属性注入那样提前暴露引用。

8. 那具体解决流程清楚吗?

Spring 解决单例属性注入循环依赖,大概流程可以用 A、B 互相依赖来理解。

创建 A 的时候,Spring 会先把 A 实例化出来,但这时 A 还没有完成属性注入和初始化。为了避免后面别人依赖 A 时拿不到对象,Spring 会把一个能获取 A 早期引用的 ObjectFactory 放到第三级缓存里。

接着 A 做属性填充,发现需要 B,就去创建 B。B 也会先实例化,并且提前暴露。然后 B 属性填充时发现需要 A,这时候 Spring 会从 A 的第三级缓存里拿到 ObjectFactory,通过它拿到 A 的早期引用,放到二级缓存,并注入给 B。

B 完成初始化后进入一级缓存。然后回到 A,A 就可以注入已经创建好的 B,最后 A 也完成初始化,进入一级缓存,同时清理之前的早期引用缓存。

这里要注意,ObjectFactory 不是重新创建 A,而是返回 A 的早期引用;如果 A 需要 AOP,它返回的可能就是代理对象。

9. 构造方法出现了循环依赖怎么解决?

构造器循环依赖 Spring 默认是解决不了的。比如 A 的构造方法需要 B,B 的构造方法又需要 A,这时候 A 和 B 都还没实例化完成,Spring 没有任何一个早期对象可以提前暴露,所以三级缓存也救不了。

解决上,我一般不会优先想着硬绕过去,而是先看是不是设计有问题,比如把互相依赖的逻辑抽到第三个服务里,或者重新拆分职责。如果只是技术上要临时打破这个循环,可以用 @Lazy,让其中一个依赖注入懒加载代理对象;也可以改成 Setter 或字段注入,让对象先实例化出来,再做属性填充。但从设计上看,构造器循环依赖通常是不太好的信号。

10. SpringMVC的执行流程?

(SpringMVC = Java 后端接收请求、调用 Controller、返回响应的框架。 )

SpringMVC 的核心入口是 DispatcherServlet。请求进来后,先由 DispatcherServlet 接收,然后通过 HandlerMapping 找到对应的 Controller 方法,同时拿到相关拦截器。

接着 DispatcherServlet 会交给 HandlerAdapter 去真正调用 Controller。在这个过程中,SpringMVC 会完成参数解析、数据绑定、类型转换这些工作。Controller 执行完之后会返回结果。

如果是传统页面请求,返回的可能是 ModelAndView,然后通过 ViewResolver 解析视图,最后渲染页面返回给浏览器。

如果是现在常见的 REST 接口,比如 @RestController,一般不会走视图解析,而是通过 HttpMessageConverter 把返回对象转成 JSON,再写回响应体。

11. Springboot自动配置原理

Spring Boot 自动配置的入口一般是 @SpringBootApplication,它里面包含了 @EnableAutoConfiguration,这个是自动配置的核心。

@EnableAutoConfiguration 会通过 @Import 导入 AutoConfigurationImportSelector,然后去加载自动配置类清单。老版本主要是从 META-INF/spring.factories 里读,Spring Boot 3 之后主要是从 AutoConfiguration.imports 里读。

这些自动配置类不会无脑生效,而是会配合很多条件注解判断,比如 classpath 里有没有某个类、用户有没有自己定义 Bean、配置文件里有没有开启某个属性。只有条件满足时,Spring Boot 才会把对应的 Bean 注册到容器里。

12. Spring 的常见注解有哪些?

Spring 常见注解我一般按使用场景来分。

第一类是 Bean 注册,比如 @Component,以及它的语义化扩展 @Service、@Repository、@Controller。

第二类是依赖注入,比如 @Autowired、@Resource、@Qualifier。

第三类是配置相关,比如 @Configuration、@Bean、@ComponentScan。

第四类是 Web 开发里常用的,比如 @RestController、@RequestMapping、@GetMapping、@PostMapping、@RequestBody、@ResponseBody。还有事务相关的 @Transactional,AOP 相关的 @Aspect、@Around、@Pointcut。

如果是 Spring Boot 项目,还会常用 @SpringBootApplication,它是启动类上的复合注解。

相关推荐
用户13051807121514 分钟前
JDBC学习DAY2:从Statement到PreparedStatement
java
蛋蛋的就会顺顺的41 分钟前
hot100——矩阵
java·数据结构·算法·leetcode·力扣
周杰偷奶茶1 小时前
【Java】数组的定义和使用(附管理系统实战案例)
java·开发语言
橙子圆1232 小时前
JUC之集合类不安全
java·开发语言
谢亮_vipxieliang3 小时前
Stream API 不是银弹:常见坑与性能建议
java·开发语言
源码宝3 小时前
Web‑PACS 云影像源码|Java+Vue3 医院影像管理系统完整方案
java·源码·影像pacs·成品源码·医院影像系统
ShineWinsu3 小时前
对于Redis:string类型的解析
java·c++·redis·分布式·缓存·面试·string
三8445 小时前
Fastjson 漏洞 · 02 · autoType 机制与 checkAutoType
java·fastjson
无限码力5 小时前
小红书笔试真题 9.17 - 待发热度重排(C++/Py/Java /Js/Go)
java·小红书·小红书笔试真题·小红书技术岗笔试真题