Spring知识点

  • Spring框架
    • 依赖注入控制反转的介绍

      • 控制反转指的是一个过程,将原本对象自己控制的依赖关系变成外部容器来进行控制
      • 依赖注入是它的实现方式,Spring容器通过构造函数或者setter方法将依赖关系注入到对象中
    • Bean注入方式

      • 引导加载方式:通过Xml文件或者Java注解(@Bean注解)来实现
      • 自动配置:即
        ①自动装配(声明setter方法@Autowired 根据类进行匹配,多个则根据名字匹配(设置**@Qualifier注解可以指定Bean的名称)(设置required参数可以让其在找不到时不报错**),@Resouce JDK提供的 查找方式反一下)(在Bean上使用**@Primary注解可以设置多个匹配时的主类**。)
        ②组件扫描(@ComponentScan注解 默认会在当前包路径下扫描)
      • 自动装配的过程:再创建上下文时进行注册Bean定义,在Bean的实例化时进行解析(根据注解类型来选择执行Bean的后置处理器进行解析)
    • Spring IoC容器加载的流程

      • 注册容器时,会先注册启动配置类,然后调用refresh()方法启动容器
      • 准备初始化,对其设置启动日期和状态标志以及初始化监听器容器
      • 初始化Bean工厂加载Bean定义为其设置类加载器,添加后置处理器,注册系统环境等必要组件
      • postProcessBeanFactory()留给子类的钩子方法,用来对工厂后处理然后实例化并调用所有的工厂后置处理器
        • 为什么先加载工厂后置处理器:因为Bean定义在IoC容器加载时会先进行注册,而工厂后置处理器要对加载完的Bean定义进行扩展用的,所以要先加载。(比如解析配置类Bean工厂后置处理器
      • 国际化消息的相关支持方法(默认的消息器会将消息传给父类(如果有的话),本身无实际作用)
      • 初始化Spring容器的事件广播器(以支持事件监听)(如果用户未定义自己的广播器,则会创建一个默认的)。
      • onRefresh()留给子类的钩子方法,用以注册特殊的Bean等(如Spring Boot在此注册Servlet容器
      • 注册事件监听器,将它们加入到刚才的事件广播器中
      • 实例化Bean
      • 创建容器完成,发布最终事件。
    • 容器加载过程的扩展点:postProcessBeanFactory方法,onRefresh()方法

    • Spring启动过程相关的扩展点:

      • 钩子方法
      • Bean工厂加载过程:Bean工厂后置处理器,Bean定义后置处理器,环境后置处理器
      • ImportSelector接口返回一个类全限定名称的数组集合,Spring会根据这个数组解析Bean定义
      • ImportBeanDefinitionRegistrar接口,提供Bean定义的注册器,由用户将Bean定义传入
      • Bean的加载过程:
        ① Aware接口(设置Bean名字,类加载器,Bean工厂的方法)。
        ② Bean的后置处理器Bean初始化的前后进行调用)。
        ③ InitializingBean接口,在Bean初始化后调用。
        ④ @PostConstruct注解,在Bean初始化后调用。
        ⑤ 使用init-method声明了初始化方法,在Bean初始化后调用。
        ⑥ DisposableBean接口,在Bean销毁后调用。
        ⑦ @PreDestroy,在Bean销毁后调用
        ⑧ 使用destory-method 声明销毁方法,在Bean销毁后调用。
        ⑨ FactoryBean接口:自定义Bean的创建逻辑。
      • 监听器扩展,监听Spring中发布的相关事件
      • ApplicationRunner / CommandLineRunner接口,在上下文刷新后提供扩展点(Spring Boot)
    • Bean的加载过程

      • 先判断Bean是否为单例模式或者实现了SmartFactoryBean接口(FactoryBean的扩展接口)
      • 判断成功,会去一二级缓存中找,找到则返回,如果三级缓存中有值,则调用缓存中的工厂方法创建Bean返回,如果都没有,则继续执行。
      • 执行Bean实例化后将Bean包装成一个工厂加入三级缓存
      • 根据Bean定义反射调用setter方法进行属性注入(此时会实例化别的Bean)
        • 如果又再次回到开头,则会调用三级缓存的工厂方法,返回实例化的对象
      • 相关属性注入完成,再次去一二缓存中找(没有三),防止重复创建动态代理
      • 如果没有,则开始进行初始化流程,调用相关扩展接口加入到一级缓存
    • 三级缓存的作用
      一级缓存:保存创建好的Bean
      二级缓存:存储已经实例化但尚未完成初始化的Bean
      三级缓存:存储的是早期的对象工厂

      • 二级缓存行不行
        Spring中的三级缓存是为了AOP服务的,如果实现AOP则从三级缓存拿到的实例化对象是AOP代理对象,如果使用二级缓存,则需要在注入属性时直接注入代理类,这不符合Bean的生命周期,Bean的AOP创建应在初始化后调用AOP的后置处理器创建代理
      • 多例Bean无法进行循环依赖:依赖循环没有出口,因为每次都会创建实例。
      • 构造函数无法进行循环依赖(Spring无法直接解决):
        构造器注入,会在通过构造函数实例化时就直接注入属性
        此时可以加上**@Lazy注解**,让其注入时返回一个空对象,跳出依赖循环即可。
      • Bean的并发创建双重检查锁
        在第一次查找缓存时,会对二三级缓存上锁(一级缓存不上锁,是为了减少性能影响),等线程创建完成对象加入一级缓存后锁会被释放,同时唤醒后的线程因为找不到缓存(一级缓存已经找过了),则执行后面的逻辑,在依赖注入完成后,会再次上锁查找缓存(名字的由来),避免重复创建
    • 加载第三方的Bean:

      • @Bean的方式来配置第三方类
        @Import直接导入类的方式
    • FactoryBean的作用以及原理

      • 它是一个接口,其中的getObject方法就是用来获取其产生的对象(且是懒加载的)
    • Spring相关的重要注解

      • 常见注解的功能
    • Spring AOP(运行时增强)(常见的还有AspectJ AOP (编译时增强))

      • 实现方式:JDK(针对接口的实现类)CGLib(生成子类去重写)
        配置类中通过注解开启AOP支持(可以在此处设置在线程中暴露代理对象参数,这样就可以通过AOP的上下文拿到当前增强的对象,防止出现本类方法互相调用时AOP失效问题。)
      • 具体使用
        ①基于接口的配置。
        ②@AspectJ注解配置。
        ③AspectJ直接实现。
      • 实现原理:基于动态代理,代理类会封装目标类,并拦截被通知的方法的调用,执行切面逻辑,再将调用转发给目标类。采用责任链的设计模式。
        当配置类设置AOP启动参数,会注入一个AOP的Bean后置处理器,在初始化前会解析切面注解并缓存,初始化后会拿到之前的缓存,判断是否被切点命中,创建代理
      • 失效的原因:
        –类内部调用方法失效(设置线程暴露参数,或者直接注入本类,然后调用
        –方法是private或者static(无法继承,实际上除了public都不行
        –目标类没有配置为Bean
    • 事务

      • 四大特性:
        原子性:所有操作要么全部成功,要么全部回滚
        一致性:事务执行前和执行后必须处于一致性状态
        隔离性:并发访问数据时,多个事务互相不干扰
        持久性:事务一旦提交,对数据库的更改就是永久
      • 实现方式编程式事务管理(编程的方式,灵活但难维护)和声明式事务管理(注解或xml配置,清晰方便))
        • 传播行为
          事务的传播行为指的是当一个事务方法调用另一个事务方法时,这个事务应该如何运行。
          通过设置注解中的propagation参数,常见有三种:
          默认的无事务调用时会开启新事务有事务调用时会融合外部事务(适合增删改
          SUPPORTS无事务调用不开启事务,有事务调用时会融合外部事务(适合查询
          REQUIRES_NEW无事务调用和有事务调用都会开启新事务日志等)
        • 隔离级别
          依赖数据库的事务隔离级别,通过注解中的isolation参数设置()
          脏读(RC)
          不可重复读(RR)
          幻影读(SERIALIZABLE)
      • 实现原理(针对声明式事务管理)
        基于AOP实现的(要在配置类中通过注解开启事务注解支持
        会为此类创建一个代理,调用会加上try-catch语句块
        Spring事务信息存放在ThreadLocal中,所以一个线程只能有一个事务
        • try:
        • 判断ThreadLocal是否有数据库连接,如果,说明现在是内嵌事务,执行下面语句:
          • 如果是融入行为:不会重新创建新事务,将新事务的标志字段改为false
          • 如果是创建行为:会将事务状态信息暂存后清空,重写创建一个事务
        • 否则正常创建数据库连接,并且修改自动提交为false执行目标方法
        • catch:出现异常,需要回滚就会回滚,否则正常提交
        • 无异常执行完成,当新事务标志字段为true提交事务,否则恢复被清理的旧事务
    • 事件监听机制(观察者设计模式

      • 实现原理:底层通过事件广播器来发布事件,可以自定义事件监听器,Spring容器会帮我们自动加入进去。

Spring Boot

  • Spring Boot框架
    • 与Spring的主要区别
      • 两者关系:Spring Boot不像Spring,不是一个框架,它是一个可以快速构建Spring脚手架工具,为其开发提供便利
      • 核心注解:
        @SpringBootApplication(其为复合注解,还包括**@EnableAutoConfiguration @SpringBootConfiguration**)
      • 内嵌Servlet容器
    • Spring Boot的启动流程
      • 运行main方法初始化SpringApplication(发布事件)
      • 运行run方法,内部会读取环境变量,打印Banner,设置一些参数等(发布事件)
      • 创建SpringApplication上下文与初始化上下文,将启动类作为配置类注册
      • 调用refresh方法加载IoC容器(发布事件)
        • 解析**@Import加载的所有自动配置类**
          自动配置类目的就是为我们做第三方库的自动配置
        • onRefresh方法中会创建servlet容器
      • 执行扩展接口ApplicationRunnerCommandLineRunner接口)(发布事件)
      • 执行异常也会发布事件
      • 大量利用监听器进行扩展(监听事件的发布)
    • 自动配置加载的原理:
      • 通过**@SpringBootConfiguration映入了@EnableAutoConfiguration**注解
      • 其中使用**@Import导入了一个deferredImportSelcetor**
      • 加载IoC容器时会解析@Import注解
      • 读取所有jar包META-INF/spring.factories文件(SPI),过滤出所有AutoConfigurationClass类型的类
      • 通过**@Condition排除无效的自动配置类**
    • 内嵌Servlet容器启动原理(默认Tomcat
      • 引用了web的场景启动器,就会导入容器启动的自动配置类,会导入一个Web容器工厂,在OnRefresh方法创建容器
      • Jar包能直接运行的原因
        • Spring Boot提供了一个maven插件,此时打包会将依赖的jar包和Spring Boot相关的类一起打包。
          同时启动时会分别加载依赖的jar包和启动Main函数。
      • Servlet相关概念
        • 三大组件
          Servlet:处理客户端请求的核心组件
          Listener:用于监听 Web 应用程序中各种事件的组件
          Filter:用于在请求到达 Servlet 之前或响应返回客户端之前对请求和响应进行处理的组件
        • Spring Boot可以在配置类中的注册 注册器Bean,并在其中注册相关组件
    • 日志框架和门面
      • 日志实现的方式有非常多,为了统一各个日志框架与日志门面,出现了适配器(让不同日志门面统一实现SLF4J门面)和桥接器(让不同日志框架实现SLF4J门面),只需要加入不同的适配器和桥接器就可以实现日志的整合。
    • Spring MVC测试方法
      • MockMvc
        • 不需要启动Web应用,可以对http请求进行模拟,同时提供一套验证工具,在测试类注入MockMvc对象,测试类加上**@AutoConfigureMockMvc**即可使用。
      • RestTemplate
        • 主要适用微服务远程调用(本地也行),在普通类中的构造函数可以通过builder构造一个
          测试类通过TestRestTemplate直接new一个。(使用完整的远程调用请求路径,以及需要使用无参构造函数)
      • PostMan/ApiPost工具
      • Swagger API测试文档

SSM

  • SSM框架
    • Spring MVC
      • 工作流程:
        • 客户端向服务器发送一个HTTP请求
        • 前端控制器DispatcherServlet)接收请求
        • 根据请求的URL和其他信息,通过HandlerMapping确定请求应该由哪个**处理器(Controller)**来处理
        • 确定处理器后DispatcherServlet会通过HandlerAdapter调用处理器
        • 处理器(Controller)具体的业务逻辑实现类,它接收请求参数,执行业务逻辑,并返回一个ModelAndView对象。
        • 返回ModelAndView对象后,DispatcherServlet会通过**视图解析器(ViewResolver)**解析视图名称,去找到对应视图。
        • 找到视图资源后,DispatcherServlet将模型数据传递给视图,并进行渲染
        • 最后,DispatcherServlet 将生成的响应内容发送回客户端,客户端(如浏览器)会显示响应内容
      • HandlerInterceptor:用于拦截处理请求,可以在请求处理前、处理中和处理后执行特定逻辑。
      • ControllerAdvice:用于全局处理控制器的异常、数据绑定和数据校验
    • Spring 详细戳这
    • Mybatis
    • 三层架构
      • 表示层
      • 业务逻辑层
      • 数据访问层