spring-八股文

  1. 对IOC的理解
  2. inverse of control,控制翻转,将bean的生成交给spring管理,例如,@autowired自动装配的mapper层对象。
    好处:单例bean可以有效复用,减少对象生成的时间成本。各种bean还有自身的应用场景。
    
  3. 单例bean与单例模式
  4. spring自动装配出来的对象全都会指向同一个单例bean,不强制约束用户不可创建第二个对象。
    单例模式针对的是类而言的,如果某个类应用了单例模式,那么这个类就不可能创建出第二个对象,所有该类的引用都会指向同一个对象,不管是spring自动装配还是用户自己new
  5. spring事务传播机制
  6. 事务注解对应的方法A,调用了方法B,那么B是共用一个事务的逻辑,还是单独开一个新事务,,,,这些策略取决于两个方法定义的事务传播类型
    
    1. REQUIRED(Spring默认的事务传播类型):如果当前没有事务,则⾃⼰新建⼀个事务,如果当前存
    在事务,则加⼊这个事务
    2. SUPPORTS:当前存在事务,则加⼊当前事务,如果当前没有事务,就以⾮事务⽅法执⾏
    3. MANDATORY:当前存在事务,则加⼊当前事务,如果当前事务不存在,则抛出异常。
    4. REQUIRES_NEW:创建⼀个新事务,如果存在当前事务,则挂起该事务。
    5. NOT_SUPPORTED:以⾮事务⽅式执⾏,如果当前存在事务,则挂起当前事务
    6. NEVER:不使⽤事务,如果当前事务存在,则抛出异常
    7. NESTED:如果当前事务存在,则在嵌套事务中执⾏,否则REQUIRED的操作⼀样(开启⼀个事
    务)
    
  7. spring事务什么时候会失效-√
  8. 数据库:数据库如果不支持事务,那么spring事务就会失效
    Java:
    类:事务所在类没有对应的注解,spring没有在容器里面生成该类的bean[类上面没有component之类的注解]
    方法:方法上没有加上事务注解或者方法的权限修饰符不是public
    调用:调用方法没有使用代理对象,而是通过原对象调用的方法。[自己new]
    
  9. spring中创建的bean,生命周期有哪些-※
  10. 1.推断构造方法
    2.实例化
    3.依赖注入[构造方法可能需要部分外部注入属性;成员变量中依赖于其他类,等等多种需要将其他实例注入的情况]
    4.处理@postConstruct注解,构造之后还可以执行的自定义处理
    5.处理initializingBean接口复写内容,如果实现了该接口的话[前面就是bean的实例化,这一步就是bean的初始化,这就是两者的区别]
    6.生成代理对象,最后生成bean
    
  11. spring中的bean是线程安全的吗?
  12. 如果bean上有状态,就不是线程安全的
    如果bean上没有状态,就是线程安全的
    
  13. applicationContext和beanFactory有什么区别?
  14. beanFatory的功能,applicationContext都有,但applicationContext还有其他功能[获取系统环境变量、事件发布]
    
  15. spring中的事务是如何实现的?
  16. 事务这个概念是数据库层面的,spring只是基于数据库的事务功能,对其进行了扩展,提供了方便开发人员操作事务的方式
    
    1.针对使用了Transaction注解的bean,生成代理对象
    2.当调用了事务方法,创建新的数据库连接,并关掉自动提交功能
    3.然后执行当前方法,会执行若干SQL
    4.执行以后,没有发生异常,直接提交该事务
    5.执行以后,发生异常,进行回滚[需要回滚的异常级别,在@Transactional注解中的rollbackFor属性配置]
    
  17. spring容器的启动流程是怎样的?(IOC的工作流程)
  18. 定义:IOC,inverse of control,即控制反转,将bean的创建管理交给spring,有利于单例bean的复用,单例bean还能减少对象创建的时间成本,还能降低对象与对象之间的耦合性。
    
    
    1.扫描所有beanDefinition对象,将其保存到beanDefinitionMap集合中
    2.通过对beanDefinitionMap遍历,可以逐个实例化bean对象,推断构造方法-实例化-依赖注入-postConstruct注解-beanInition接口复写方法-生成代理对象-生成bean
    3.applicationContext发布spring容器启动事件
    4.多例bean与lazy修饰的单例bean只有使用到的时候,才真正初始化完成,在使用之前,仅有一个代理对象作为依赖注入
    

    工作流程:

    IOC容器初始化,解析注解,配置类等方式得到beanDefinition,将其保存到beanDefinitionMap集合中

    通过对beanDefinitionMap遍历,可以逐个实例化bean对象

    bean的初始化以及依赖注入,如果有循环依赖就用三级缓存-singletonObjects-earlysingletonObjects-singletonFactories

    通过注解或者beanFactory可以使用bean,同时懒加载的bean对象也是使用阶段的时候,才真正初始化完成的.使用之前,只是通过代理对象先生成对应的实例对象.

  19. spring用到了哪些设计模式?
  20. 1.beanFactory-工厂模式
    2.单例bean-单例模式
    3.代理对象-代理模式
    
  21. spring boot常用注解及其底层实现-※
  22. 常用注解有
    1.@bean 方法级注解,可用于对应的单例bean对象
    2.@autowired 用于生成单例bean的引用;要求原类增加类注解例如component\service\controller\mapper等来交给spring托管
    3.@controller\@service\@mapper,这三都是类注解,用于指定controller、service、mapper类,从而可以自动将请求匹配到controller对应方法上,以及自动调用对应的SQL
    4.@GetMapping@PostMapping,用于指定请求的匹配类型,方法接收get请求、post请求等等
    
    具体实现 不太清楚
    
  23. springboot是如何启动Tomcat?
  24. 1.检索是否有tomcat依赖
    2.将tomcat实例化,并加入到spring容器中
    3.启动tomcat实例
    
  25. spring cloud 有哪些组件?
  26. springboot如何解决跨域问题?
  27. 1.实现webMvcConfigurer接口,实现addCoresMapping方法
    2.利用注解@CrossOrigin,加到spring boot容器对象上即可
    
  28. @component和@bean之间的区别
  29. 1.用途不同:component声明的是一个普通类,而bean则是在配置类中声明和配置一个bean对象
    2.声明不同:component应用的是类 ,而bean应用的是方法上
    3.控制不同:component的创建配置过程是由spring管理的,而bean的创建配置过程允许开发人员手动控制
    
  30. 过滤器和拦截器之间的区别
  31. 过滤器:filter
    拦截器:interceptor[例如操作日志记录的AOP]
    
    1.filter在请求达到servlet之前,interceptor在servlet容器收到请求之后,进入controller之前运行
    2.filter依赖于servlet容器[实现的是javax.servlet.Filter接口],interceptor是spring的一个组件[实现的是handlerinterceptor接口]
    3.filter基于函数回调,interceptor基于java反射机制
    
    filter-->interceptor.prehandle-->handler-->interceptor.posthandler-->interceptor.afterCompletion-->filter
    
  32. @Async一定会异步执行
  33. A:被@Async标记的方法
    B:调用A的方法
    
    @Async:
    这是一个标记方法为异步执行的注解
    spring框架会默认使用一个线程池来管理异步方法的执行,spring框架将A封装成代理对象[这也就是为什么A必须是托管的bean对象的原因],B调用A的时候,实际上都是使用线程池来执行A的方法体
    
    这个注解只是标记A是异步执行的,真正是否异步执行,取决于:
    
    一、要打开功能-@EnableAsync-@Async
    二、必须能创建代理对象
    2.1 类:spring托管
    2.2 方法:必须是public[新版spring貌似protected也可以]
    2.3 方法:不能是静态-否则无法创建子类来代理[Spring用的应该是CGLIB]
    
    三、必须要使用代理对象
    3.1 调用方与被调用方不能在同一个对象内-否则会绕过代理对象
    
    四、合理配置线程池
    4.1.使用@Async必须配置一个合适的线程池来执行异步方法。
    [一般spring默认就配置了线程池,但是默认的线程池不是真正的线程池,并没有真正复用线程]
    [也可以自定义重新指定线程池,通过对ThreadPoolTaskExecutor进行封装即可,指定
    1.setMaxPoolSize
    2.setCorePoolSize
    3.setThreadNamePrefix
    4.initialize
    即可将对象返回给注解--->@Async("asyncTaskExecutor")
    ]
    
  34. 为什么有些公司会禁用Transaction注解
  35. 事务注解主要存在以下隐患
    正常情况:如果事务耗时较长,那么占用锁时间也会较长,甚至有可能耗尽数据库连接池,影响程序的正常执行
    非正常情况:如果事务中还存在嵌套情况,有可能造成未知的异常情况
    项目:随着项目的复杂程度提升,事务的控制逻辑越来越复杂,降低了代码的可读性与可维护性
    
  36. @Conditional的作用
  37. 作用是给 bean是否装载到容器 增加一个条件判断
    入:注解接受一个或多个实现了condition接口的类;condition接口里面有一个matches方法需要重写
    出:可以修饰在类上面,也可以修饰在方法上面。
    
  38. springMVC的理解
  39. springMVC是spring生态下,基于MVC架构设计的webFramwork模块,是一种web框架
    M:model,模型
    V:view,视图
    C:controller,控制器
    其组件主要有:前端控制器(dispatcherServlet),控制器映射器(handlerMapping),控制器适配器(handlerAdapter),视图解析器(viewResolver)
    其主要执行流程见《spring MVC执行流程》
    
  40. spring MVC执行流程
  41. 请求获取处理器

    请求执行处理器

    调用处理器

    逻辑视图和数据

    逻辑视图和数据

    依据逻辑视图寻找物理视图

    用户发送请求

    前端控制器

    处理器映射器,MAP结构,用于找到URL对应的controller

    处理器适配器,实际controller调用方,由于早期不止注解一种方式,这里是用来做兼容适配的

    处理器,开发实际编写的controller

    视图解析器

    请求获取处理器

    请求执行处理器

    调用处理器

    ModelAndView

    ModelAndView

    ModelAndView转为View

    用户发送请求

    dispatcherServlet

    handlerMapping

    handlerAdapter

    controller,如果有拦截器,进入之前会先执行拦截器

    viewResolver

  42. 什么是循环依赖?
  43. 循环依赖就是在spring在构建单例bean对象的时候,依赖注入阶段,AB互相之间有依赖关系
    往A注入B的时候,单例池里面既没有A也没有B,触发B的构建,往B注入A的时候,由于单例池里面没有A,又会触发A的构建,
    从而导致无法正常实例化、初始化这些单例bean
    
  44. 什么是三级缓存?
  45. 三级缓存是解决循环依赖的一种解决方案
    第一级缓存 singletonObjects<beanName,单例 bean>:用于保证所有bean是单例的
    保存的是 经过完整生命周期,创建完成的单例bean对象
    
    第二级缓存 earlySingletonObjects<beanName,单例bean>:用于防止出现多代理问题
    保存的是,在出现循环依赖的情况下,自己都没有创建完,需要提前暴露给其他单例bean用的单例bean对象
    
    第三级缓存 singletonFactories<beanName,()->getEarlyBeanReference(beanName,mbd,bean)>:用于打破循环
    保存的是bean对应的普通对象,用于循环依赖的时候,能提供一个普通对象,用于生成代理对象
    
    基本流程:
    背景:A->B[A依赖于B]    A->C[A依赖于C]
    
    1.构建A的普通对象-->保存到第三级缓存,用于之后调用打破循环
    1.x 记录creatingset 判断循环依赖
    2.B依赖注入:
      2.1 构建B的普通对象-->保存到第三级缓存,用于之后调用打破循环
      2.2 找依赖对象A:单例池->earlySingletonObjects->singleFactories->返回代理对象->earlySingletonObjects
      2.3 依赖注入,@postConstruct,initializeBean接口实现,生成代理对象,放入单例池[AOP等一系列操作]
      2.4 生成的B代理对象返回给A
    
    3.C依赖注入:
      2.1 构建C的普通对象-->保存到第三级缓存,用于之后调用打破循环
      2.2 找依赖对象A:单例池->earlySingletonObjects
      2.3 依赖注入,@postConstruct,initializeBean接口实现,生成代理对象,放入单例池[AOP等一系列操作]
      2.4 生成的C代理对象返回给A
    
    4.通过earlyProxyReference判断是否需要继续AOP等操作
    5.取出earlySingletonObjects提前放入的代理对象,放入单例池[由于二级缓存里面存放的是三级缓存造出来的代理对象,三级缓存是通过当前的普通对象造的,因此,本质上应当是同一个对象引用]
    
  46. @Lazy的作用
  47. 1.当构造函数带参的时候,spring是无法通过三级缓存解决循环依赖的问题
    2.lazy可以通过将bean代理对象直接依赖注入,从而打破循环,直接实例初始化成功
    3.直到用的时候,才会去找容器对应的bean对象的方法
    
  48. 自动装配的基本原理
  49. 定义:自动装配简而言之就是将第三方依赖的bean自动装载到IOC容器里面,不需要开发人员去写bean的配置信息
    
    使用:
    1.引入spring-boot-starter依赖
    2.@SpringBootApplication注解开启功能,这是一个复合注解,实际是@EnableAutoConfiguration注解开启的功能
    
    该功能的实现主要依赖于以下三步:
    1.引入依赖的时候,第三方依赖里面应当包含@Configuration配置类,以@Bean注解的方式声明
    2.这个配置类的的全路径应当写入,classpath:/META-INF/spring.factories,这个文件里面[默认情况下,一般官方组件已经完成这步骤了,有需要的话,就要自己修改],SpringFactoriesLoader加载这个文件以后,spring就知道了对应的bean在哪里了。
    3.知道bean在哪里以后,ImportSelector 接口就能动态加载这些bean。
    
  50. @Resource与@autowired的区别
  51. 两个注解都可以用于声明bean对象
    @autowired
    类型:可以
    名称:必须搭配@qualified注解同时使用
    
    @Resource
    类型:可以
    名称:可以
    
  52. SpringBoot中约定优于配置的理解
  53. 解释:约定大于配置,是一种开发理念,核心思想是让开发人员减少对配置项的维护,从而聚焦于业务逻辑
    
    spring boot如何体现:
    spring boot本身就是这个理念的产物,它类似于一个脚手架,方便开发人员快速spring生态下的应用程序
    
    1.jar包依赖管理
    2.自动装配机制中的第三方组件集成
    3.应用部署到容器
    4.默认加载application配置文件
    
  54. ResponseBody的作用
  55. 声明 将接口方法的返回值转成JSON字符串 并输出
    
    原先没有该注解 仅返回给前端数据 数据由前端界面接收
    有了该注解 会将返回值转成JSON字符串 并放入一个模板HTML的body里面 从而输出到浏览器
    
  56. Controller与RestController的区别?
  57. ``` RestController=Controller+responseBody ```
posted @   356a  阅读(170)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示