springboot理论知识汇总

思维导图

MVC

HTTP请求处理流程

请求处理流程

参数绑定

  • 不同注解修饰的参数都有支持的方法参数处理器,例如@RequestParam对应的是RequestParamMethodArgumentResolver
  • 在请求处理流程中的调用目标方法环节,会使用对应的参数处理器解析参数

过滤器、拦截器、AOP执行顺序

执行顺序

IOC

bean的加载过程

bean的加载过程
  1. 注册BeanFactory后置处理器
  2. 通过BeanFactory后置处理器扫描出所有需要spring管理的类
  3. 通过BeanFactory后置处理器封装成BeanDefinition加载到BeanFactory
  4. 创建非延迟加载的bean实例

Bean实例化的过程

  1. 执行实例化前操作
  2. 创建Bean实例
  3. 将Bean缓存起来
  4. 给Bean填充属性值
  5. 初始化Bean
    (1) 执行BeanPostProcessor-postProcessBeforeInitialization
    (2) 执行InitializingBean->afterPropertiesSet
    (3) 执行initMethod
    (4) 执行BeanPostProcessor-postProcessAfterInitialization

spring是如何解决属性循环依赖的

Bean实例化的过程如上,第三步缓存bean就是为了解决循环依赖的,例如:A与B属性循环依赖。

  1. A执行第二,三步,调用构造函数并将实例加入缓存;
  2. A执行第四步时找不到B实例,于是先去执行B的实例化;
  3. B执行到第4步时从缓存中能够找到A实例,于是B实例化成功;
  4. 接着再执行A的实例化。

为什么spring无法解决构造方法中的循环依赖

调用构造函数后是第二步就要执行的事情,第二步都通过不了,自然就无法执行第三步加入缓存中。

Bean的生命周期

image.png
  1. BeanDefined
  2. BeanFactoryPostProcessor对BeanDefined后置处理
  3. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation实例化前执行
  4. Bean实例化
  5. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation实例化后执行
  6. 属性注入
  7. BeanNameAware.setBeanName
  8. BeanFactoryAware.setBeanFactory
  9. ApplicationContextAware.setApplicationContext
  10. BeanPostProcessor的前置方法
  11. InitializingBean.afterPropertiesSet方法
  12. @PostConstruct修饰的方法
  13. BeanPostProcessor的后置操作
  14. DisposableBean.destory销毁
  15. @PreDestroy修饰的方法

有几种注入方式

set 注入,构造器注入和方法注入

BeanFactory和FactoryBean的区别

  • BeanFactory是Spring容器中的一个很重要的类,它对于Bean的创建有一个统一的流程
  • FactoryBean是一个工厂Bean,可以生成某一个类型Bean实例,它最大的一个作用是:可以让我们自定义Bean的创建过程

spring的工厂模式是怎么实现的?

  • spring的工厂模式实际上是抽象工厂模式
  • 它允许用户为指定Bean自定义工厂
  • 其他Bean会采用默认的一套流程生成Bean

自定义工厂类

  • 自定义工厂类实现FactoryBean接口
  • 实现getObject方法(获取对象的方法)
  • @Component改名

AOP

代理模式有哪几种

静态代理、JDK动态代理、CGLib动态代理

  • 静态代理,即对象的适配器模式
  • JDK动态代理,生成被代理接口的匿名类作为代理类
    1. 动态代理类实现InvocationHandler接口
    2. Proxy.newProxyInstance生成代理对象
    3. 被代理类需要有接口
  • CGLib动态代理,生成被代理类的子类作为代理类
    1. 创建Enhancer
    2. 创建MethodInterceptor接口实现类
    3. Enhancer.setSuperclass(被代理类)
    4. Enhancer.setCallback
    5. Enhancer.create生成代理类

JDK动态代理的原理

  1. 为接口创建代理类的字节码文件
  2. 使用ClassLoader将字节码文件加载到JVM
  3. 创建代理类实例对象,执行对象的目标方法
  4. 通过反射方式调用被代理类相应的方法

springboot如何选择代理模式

  • 有接口,使用JDK动态代理(1.8后JDK动态代理效率高于CGLib动态代理)
  • 无接口,使用CGLib动态代理

MyBatis

事务控制的原理

  • 调用spring管理的bean的方法,实际上是通过代理类实现的
  • 当识别到方法被@ Transactional修饰时,会执行事务拦截器
  • 在事务拦截器中,开启事务
  • 在事务拦截器中,调用目标对象方法
  • 在事务拦截器中,提交事务或者回滚事务。

事务传播行为

  • REQUIRED (要求):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • SUPPORTS (支持):如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • MANDATORY (强制):如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • REQUIRES_NEW (要求新的):创建一个新的事务,如果当前存在事务,则把当前事务挂起。
  • NOT_SUPPORTED (不支持):以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • NEVER (都不):以非事务方式运行,如果当前存在事务,则抛出异常。
  • NESTED (嵌套):如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 REQUIRED 。
  • 指定方法:通过使用 propagation 属性设置,例如:@Transactional(propagation = Propagation.REQUIRED)
  • 默认值为REQUIRED

JDBC四大核心类

  • DriverManager,用于注册数据库连接
  • Connection,与数据库连接对象
  • Statement/PrepareStatement,操作数据库SQL语句的对象
  • ResultSet,结果集或一张虚拟表

MyBatis也有四大核心类:

  • SqlSession对象,该对象中包含了执行SQL语句的所有方法。类似于JDBC里面的Connection。
  • Executor接口,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。类似于JDBC里面的Statement/PrepareStatement。
  • MappedStatement对象,该对象是对映射SQL的封装,用于存储要映射的SQL语句的id、参数等信息。
  • ResultHandler对象,用于对返回的结果进行处理,最终得到自己想要的数据格式或类型。可以自定义返回类型。

Mybatis 原理

Mybatis核心流程图

在spring中,Mapper接口我们都没有实现的方法却可以通过依赖注册的方式使用,是为什么呢?

  • mybatis使用动态代理的方式实现了Mapper接口
  • MapperFactoryBean,spring动态代理的方式将实现的mapper对象又进行了一层分装
  • 最终,当执行mapper时,将先去获取ThreadLocal中获取sqlSession,无则创建,然后调用sqlsession.Mapper的方式获得到最终的Mapper对象。

一级缓存和二级缓存

  • 一级缓存是sqlsession级别的缓存,当调用close/clearCache或udpate时清空缓存,由于无事务时,一条sql的执行就会调用close方法,所以一级缓存只作用无同一事务中。
  • 二级缓存是应用级别的缓存,以namespace为维度。当namespace下发生增删改操作时清空缓存,分布式环境和多表操作存在问题,不推荐使用。

其他

springboot的启动流程

启动流程

springboot自动装配原理

  1. Import相关
  • 注解嵌套关系 @SpringBootApplication -> @EnableAutoConfiguration注解 -> @Import({AutoConfigurationImportSelector.class})
  • Import会将selectImports方法返回的所有全路径限定类名都会被spring扫描
  1. AutoConfigurationImportSelector相关
  • 核心方法调用链 selectImports -> getAutoConfigurationEntry -> getCandidateConfigurations -> loadSpringFactories
  • 将扫描classpath下面类路径为META-INF/spring.factories的所有文件(包括jar包),提取出key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的所有数据。
  1. ConditionalOnClass注解
  • 官方组件一般都被ConditionalOnClass注解修饰,这是由于官方组件factories文件都不和jar包放一起。
  • 它表示标记的类存在时才会被spring装配,即导入了目标jar包时才会被spring装配

当spring的事务隔离级别同mysql的事务隔离级别不一致时

  • jdbc 的使用流程有四部,注册驱动,建立连接,发起请求,输出结果
  • 其中建立连接可以指定事务隔离级别
  • 于是当spring设置的事务隔离级别同数据库不一致时,以spring为准。

@Transactional不起作为的四个原因

  • 默认RuntimeException异常才回滚,可指定
  • 异常捕捉后没有抛出
  • 修饰非public方法(事务拦截器实现的,当为非public方法时不会去获取Transactional注解信息)
  • 在类内部调用调用类内部@Transactional标注的方法(由于动态代理的机制,可以通过将内部方法调用替换为代理类方法调用来避免)
  • 修饰接口,只有通过JDK动态代理才能起作用。
  • 存储引擎
  • 事务传播等级

springboot有哪些优点

  • 独立运行,内嵌了各种 servlet 容器,Tomcat、Jetty 等,现在不再需要打成war 包部署到容器中,Spring Boot 只要打成一个可执行的 jar 包就能独立运行,所有的依赖包都在一个 jar 包内
  • 简化配置,spring-boot-starter-web 启动器自动依赖其他组件,简少了 maven 的配置。
  • 自动配置,能根据当前类路径下的类、jar 包来自动配置 bean,如添加一个 spring
    boot-starter-web 启动器就能拥有 web 的功能,无需其他配置。
  • 无代码生成和XML配置,配置过程中无代码生成,也无需 XML 配置文件就能完成所有配置工作,这一切都是借助于条件注解完成的
  • 应用监控

spring-boot-starter-parent的作用

  • 统一版本
  • 指定编码

springboot如何多环境快速切换

  • 添加application-dev.properties
  • application.properties文件中添加配置spring.profiles.active = dev

springboot如何实现热部署

导入spring-boot-devtools包

springboot封装starter组件核心

  • resources目录下创建META-INF/spring.factories文件,定义要被spring管理的配置文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.mystarter.config.MyConfig
  • 可在类上添加@Conditional标签限定实例化条件。

Spring Boot 配置加载顺序

  1. properties文件;
  2. YAML文件;
  3. 系统环境变量;
  4. 命令行参数;

Spring Boot做了什么

  • 简化配置
  • 起步依赖
  • 内嵌容器

注解大全

注解大全

你可能感兴趣的:(springboot理论知识汇总)