一、Spring框架

Spring框架概述

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

答:

不是线程安全的
Spring框架有一个@Scope注解,默认的值就是singleton(单例bean)。
因为一般在Spring的bean中都是注入无状态的对象(如:Service DAO),没有线程安全问题;但是如果在bean中定义了可修改的成员变量,就要考虑线程安全问题了,可以使用多例:prototype加锁来解决。

1.2 AOP是什么?

AOP(Aspect Oriented Programming),即面向切面编程,用于将那些与业务无关的代码抽离出来,如:日志、事务、权限验证等。封装为一个可重用的模块,称之为切面,减少系统的重复代码,降低模块的耦合度,提高系统的可维护性。

常见使用场景:

  • 日志记录
  • 数据缓存
  • 性能监控
  • 事务管理
  • 权限验证
  • 异常处理
  • 业务逻辑解耦

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

Spring中的事务是通过AOP(Aspect Oriented Programming)实现的。

  • 声明式事务:使用@Transactional注解在方法上声明事务,Spring会自动管理事务的开启、提交、回滚等操作。
  • 编程式事务:通过TransactionTemplateTransactionManager手动管理事务,需要在代码中编写事务的开启、提交、回滚等操作。

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

  • 异常捕获处理
    • 事务通知只有捕捉到目标抛出的异常,才能进行回滚
    • 如果目标自己处理掉异常,事务通知无法知悉导致事务失效。
    • 解决方法
      • catch块添加throw new RuntimeException(),手动抛出运行时异常。
  • 抛出检查异常
    • Spring默认只会回滚非检查异常(RuntimeException)
    • 检查异常是指在方法签名中声明的异常,需要在方法中进行处理或抛出。
    • 事务通知无法捕捉到检查异常,导致事务失效。
    • 解决方法
      • 事务通知(@Transactional)中添加rollback-for属性,指定需要回滚的异常类型。
  • 非public方法
    • Spring默认只会对public方法进行创建代理,添加事务通知
    • 非public方法不能被AOP代理,导致事务失效。
    • 解决方法
      • 将方法设置为public。

1.4 Spring的ben的生命周期

1.5 Spring中的循环引用

具体例子:

二级缓存解决循环依赖

但如果有对象被增强了(代理对象),那就需要用到三级缓存
对象工厂可以生成代理对象或者普通对象
三级缓存存放的是一个对象工厂,为哪些需要AOP增强的对象提供一个方法,等需要得时候再去创建

但是如果构造方法出现了循环依赖怎么解决?

1.6 Spring MVC的执行流程

以上过时 可以不用记

1.7 Springboot 自动配置原理(重点)

  • 自动配置类:@SpringBootApplication注解所在的类,负责自动配置Spring应用程序。
    • @ComponentScan 组件扫描,默认扫描引导类所在包及其子包
    • @SpringBootConfiguration 作用与@Configuration作用相同,声明配置类
    • @EnableAutoConfiguration 实现自动化配置的核心注解
      • 该注解通过@Import注解导入对应的配置选择器
      • 配置选择器根据@Conditional注解的条件判断是否生效
      • 条件判断会有像@ConditionalOnClass这样的注解,判断是否有对应的class文件
      • 生效的配置选择器会将配置信息注册到Spring容器中

1.8 Spring常见的注解有哪些

  • Spring常见注解:

    • @Component 组件扫描注解,将类标记为组件,自动扫描并注册到Spring容器中。
      • @Service
        • 服务注解,用于标注业务逻辑层的类,通常与@Component一起使用。
      • @Controller
        • 控制器注解,用于标注控制器层的类,通常与@Component一起使用。
      • @Repository
        • 数据访问层注解,用于标注数据访问层的类,通常与@Component一起使用。
    • @Autowired
      • 自动装配注解,用于将依赖的对象注入到当前类中。
    • @Qualifier
      • 限定符注解,用于指定注入的对象的名称。
    • @Scope
      • 作用域注解,用于指定Bean的作用域。
    • @Configuration
      • 配置注解,用于标注配置类,通常与@Component一起使用。
    • @ComponentScan
      • 组件扫描注解,用于指定需要扫描的包路径,自动扫描并注册组件到Spring容器中。
    • @Bean
      • 配置注解,用于标注配置类,通常与@Component一起使用。
    • @Import
      • 导入注解,用于导入其他配置类或组件。
    • @Aspect,@Pointcut,@Around,@Before,@After
      • 切面注解,用于标注切面类,通常与@Component一起使用。
  • SpringMVC常见注解

    • @RequestMapping
      • 请求映射注解,用于指定请求的URL映射关系。
    • @RequestBody
      • 请求体注解,用于将请求体中的数据绑定到方法参数上。
    • @RequestParam
      • 请求参数注解,用于获取请求参数的值。
    • @PathVariable
      • 路径变量注解,用于获取URL中的路径参数值。
    • @RestController
      • 控制器注解,@Controller + @ResponseBody
    • @ResponseBody
      • 响应体注解,用于将方法的json返回值转换为响应体。
    • @ResponseHeader
      • 响应头注解,用于指定响应的HTTP头信息。
  • Springboot注解

    • @SpringBootConfiguration
      • 组合了@Configuration,实现配置文件的功能
    • @EnableAutoConfiguration
      • 开启自动配置功能
    • @ComponentScan
      • 组件扫描注解,默认扫描引导类所在包及其子包
    • @SpringBootApplication
      • 组合了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan

1.9 MyBatis执行流程(重要)

首先要读取mybatis-config.xml文件(现在都在yml)

构建会话工厂 生产sqlSession

创建会话 包含执行sql语句的所有方法

Executor执行器 真正执行数据库操作接口,也负责查询缓存的维护

MapperStatement对象 封装了sql语句

Mybatis是否支持延迟加载

比如一个用户有多个订单,加载用户的时候可以先不加载订单列表

fetchType = lazy


Mybatis的一级、二级缓存

一级缓存存的是对象,二级缓存存的是数据

二级缓存默认是关闭的
开启:

  • 全局配置文件
  • 映射文件
  • 使用<cache/>标签让mapper生效二级缓存

什么时候会清理二级缓存中的数据?