当前位置: 首页 > news >正文

八股打卡(七)

八股打卡七

  • Spring 循环依赖
    • 什么是循环依赖
    • 如何解决循环依赖
    • 什么循环依赖无法解决
  • JDK动态代理 vs. cglib动态代理
  • Java中的反射机制
  • Spring中的设计模式
  • Spring MVC执行流程
  • SpringBoot Starter的作用
  • Java 8新特性

Spring 循环依赖

什么是循环依赖

多个Bean之间相互依赖,形成闭环。

如何解决循环依赖

Spring循环依赖的理论依据是基于Java的引用传递。当我们获取对象的引用时,field可以延后设置,但是构造器必须在引用之前。
Spring生成一个Bean需要以下过程:

  1. createBeanInstance实例化:使用构造器来创建Bean实例;
  2. populateBean填充属性:涉及多个Bean的引用;
  3. initializeBean初始化:调用spring xml中的init方法。
    发生循环依赖一般是在第一二步,构造器循环依赖和field循环依赖。
    解决Spring单例的循环依赖问题,采用三级缓存。
  4. 在singletonObjects一级缓存中获取;
  5. 如果获取不到,在earlySingletonObjects二级缓存中获取;
  6. 如果获取不到,那么在singletonFactories三级缓存中调用getOebct方法获取;
  7. 从三级缓存获取到后,将它从singletonFactories中删除,放入earlySingletonObjects中。

举个栗子
Bean A的setter方法或field依赖了Bean B的实例对象,Bean B的setter方法或field依赖了Bean A的实例对象。

  • Bean A通过构造器完成初始化第一步,被提前暴露到singletonFactories中。在第二步时,发现需要调用get(B),那么去寻找B,发现B还没被创建,那么就先创建B。
  • Bean B同样通过构造器完成初始化第一步,在第二步时,发现需要调用get(A),那么去寻找A。
  • 在singletonObjects中寻找A,找不到;去earlySingletonObjects中寻找A,找不到,去singletonFactories中寻找,找到了半成品A,继续完成初始化第二三步,B完成了初始化,被放到singletonObjects中。
  • 返回A,A从singletonObjects中获取到B,顺利完成初始化第二三步,A完成了初始化。
  • 由于B中有A的对象引用,那么B也完整地完成了初始化。

什么循环依赖无法解决

  1. 构造器依赖:三级缓存的前提是通过构造器生成了半成品的对象。
  2. prototype bean:Spring只会在需要的时候创建它,实例化它,不会缓存它,也就是不能提前暴露一个创建中的bean。

JDK动态代理 vs. cglib动态代理

  1. 基于接口&基于类
    jdk动态代理基于接口,被代理类需要实现一个或多个接口。
    cglib动态代理基于类,通过生成目标类的子类实现代理,通过继承实现代理类,不能代理final类和final方法。
  2. 性能:
    jdk动态代理通过反射调用来实现代理,创建代理的开销较小。但是频繁调用比cglib耗时。
    cglib动态代理通过字节码生成来实现代理,创建代理的开销较大。但是实际调用性能较好,没有反射调用的开销。
  3. 适用场景:
    jdk动态代理:接口驱动编程。
    cglib动态代理:没有实现接口的类。

Java中的反射机制

Java中的反射机制核心是运行时动态加载类并获取类的详细信息。本质是JVM获取class对象后,通过class对象反编译获得类的详细信息。
Java是一个先编译后运行的语言。程序中的对象类型在编译时期就确定下来了,有些类之前用不到,就没有加载到JVM中,通过反射能够动态创建对象调用属性。在编译时JVM不需要直到运行的对象是谁。

Spring中的设计模式

  1. 工厂设计模式:Spring通过工厂设计模式的BeanFactory和ApplicationContex来创建Bean。
  2. 单例模式:Spring中的Bean默认是单例模式。
  3. 代理设计模式:Spring AOP功能的实现。
  4. 模板方法模式:Spring中jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类/
  5. 包装器设计模式:项目中连接多个数据库,不同用户根据需求访问不同的数据库。
  6. 观察者设计模式:Spring的事件驱动模型。
  7. 适配器设计模式:Spring MVC中controller。

Spring MVC执行流程

  1. 用户发送请求到前端控制器DispatcherServlet。
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  3. HandlerMapping根据请求找到具体的处理器,生成处理器对象和处理器拦截器返回给DispatcherServlet。
  4. DispatcherServlet调用HandlerAdapter处理器适配器。
  5. HandlerAdapter经过适配调用具体的控制器Controller,也即后端控制器。
  6. Controller执行,返回ModelAndView。
  7. HandlerAdapter将ModelAndView返回给DispatcherServlet。
  8. DispatcherServlet将ModelAndView传给ViewResolver视图解析器。
  9. ViewResolver解析生成View。
    10.DispatcherServlet根据View渲染视图,返回响应给用户。

SpringBoot Starter的作用

SpringBoot Starter 是为了简化和加速项目的配置和依赖管理。

  1. SpringBoot Starter是预配置的模块,封装了特定功能的配置和依赖项。引入Starter依赖后,开发人员无需手动配置相关依赖和参数。常见的Starter有Spring-Boot-Starter-Web应用于Web应用、Spring-Boot-Starter-data-jpa用于数据访问,引入这些Starter后,Spring会自动配置所需的组件和Bean。
  2. Starter管理相关功能的依赖项,包括其他Starter和第三方库,能够确保它们良好协作,避免版本冲突和依赖问题。
  3. Starter的设计使得应用程序能够通过引入不同的Starter来完成模块化的开发。每个Starter专注一个功能领域,包括数据库访问、消息队列和web应用等。
  4. 开发者能够自定义Starter,用于共享和重用特定功能的配置和依赖项。

Java 8新特性

  1. lambda表达式:简洁的语言编写匿名函数。
  2. StreamAPI:使用声明式方法对集合操作,包括过滤、映射、排序、归约。
  3. 函数式接口:Consumer, Predicate, Function。
  4. 新的日期时间API:java.Time,解决了java.util.Date和java.util.Calendar的问题。
  5. 方法引用:方法引用通过方法名引用,而不是执行它。

相关文章:

  • 密码学 网络安全 科普 网络安全密码技术
  • 【vllm】Qwen2.5-VL-72B-AWQ 部署记录
  • Webshell原理与利用
  • 天津大学:《深度解读DeepSeek:部署、使用、安全》
  • 仅仅使用pytorch来手撕transformer架构(2):多头注意力MultiHeadAttention类的实现和向前传播
  • 侯捷 C++ 课程学习笔记:C++内存管理机制
  • Qt 初识
  • Unity Android出包
  • Mysql高频面试题
  • Gemini 2.0 Flash
  • AQS及派生类
  • AI日报 - 2025年3月11日
  • Spring Cloud 负载均衡器架构选型
  • 什么是 MyBatis? 它的优点和缺点是什么?
  • [NewStarCTF 2023 公开赛道]ez_sql1 【sqlmap使用/大小写绕过】
  • 万字技术指南STM32F103C8T6 + ESP8266-01 连接 OneNet 平台 MQTT/HTTP
  • Hexo博客Icarus主题不蒜子 UV、PV 统计数据初始化配置
  • (done) MIT6.S081 Lec15 Crash recovery 学习笔记
  • tcp/ip协议配置参数有哪些?tcp/ip协议需要设置的参数有哪些
  • JAVA面试_进阶部分_深入理解socket网络异常
  • 巴外交部:以军在杰宁向外交使团开火
  • 12年政企同心共织民生保障网——上海国寿与嘉定区政府创新民生综合保险项目
  • 海南省市监局与香港标准及检定中心签署合作协议,加快检验检测国际化
  • “十五五”规划编制工作开展网络征求意见活动
  • 昆明一小区火灾调查报告:七旬夫妇身亡,生前拾荒存放大量可燃物
  • 广州某科技公司遭网络攻击,境外“黑手”被锁定