谈谈你对spring的理解

  • 是一个轻量级框架,解决企业开发的问题,使开发者可以更加专注于开发
  • 他提供了很多功能,底层依赖于两个特性,DI(Dependency Injection)和AOP(Aspect-Oriented Programming)
  • IOC控制反转,指对象的调用权由开发者转为Spring容器,负责对象的所有生命周期(创建,管理等)
  • 为什么需要IOC?最重要的就是解耦。
  • 如何实现?工厂 + 反射
  • IOC是设计理念,DI是实现方式。有接口注入,setter注入和构造器注入
  • AOP的出现解决了代码重复的问题,并进行了解耦
  • AOP作为OO(面向对象)的一种补充,常用与业务行为无关,对公共逻辑进行封装,并命名为切面(Aspect)。常用于日志,权限认证和事务处理等

谈谈spring的IOC

IOC就是控制反转,指对象的管理权由程序员变为spring管理,用来解决对象管理和依赖的问题

IOC可以理解为一个对象工厂,控制反转是一种思想,而依赖注入就是实现方式了,最大的好处就降低耦合度

在注入一个对象时,很可能不是原本的对象而是代理对象(使用到了AOP)

谈谈spirng的AOP

AOP面向切面编程,解决非业务代码的抽取问题,常用于日志,事务处理,权限控制等,减少系统重复代码,降低耦合度,提供拓展性和可维护性

在spring中实现依赖是后置处理器(BeanPostProcessor)

底层利用动态代理实现,如果代理的对象实现了某个接口,那么就会使用jdk代理,否则使用cglib代理

AOP如何进行切入的,通过beanPostProcessor后置器类来干预

谈谈spring的生命周期

一般对象生命周期:java -> class -> 加载到JVM中 -> 提供使用

spring:实例化Bean -> 设置属性 -> BeanPostProcessor前置处理 -> init -> 后置处理 -> 使用 -> destroy

spring如何解决循环依赖

比如A依赖B,B依赖A。
实例化A,发现依赖B,转头去实例化B,B发现需要A,但A已经实例化了,B完成创建,返回到A中,A完成创建

spring分为了多少个模块,或者说能干什么?

图片详细见spring.io

  • spring core:框架核心部分,包括IOC(Inversion of Control)和DI

spring中使用了哪些设计模式?

  • 工厂:beanFactory
  • 单例:默认为单例模式
  • 代理:AOP用到了JDK代理和CGLIB代理
  • 模版:比如RestTemplate,JpaTemplate等,解决重复代码问题
  • 观察者:各种监听器
  • 适配器:SpringMVC过程

谈谈@Transactional注解

  • 事务分为编程式事务(手动提交回滚,侵入性强)和声明式事务(AOP)
  • 只对public起效,由springAOP决定的,拦截处理,可能影响性能
  • 基于spring的AOP机制

隔离级别—4种

指若干个并发事务的隔离程度—从前往后没

  • 读取未提交(会出现脏读、不可复读)—基本不使用
  • 读取已提交(会出现不可复读和幻读)
  • 可重复读(会出现幻读)—默认级别
  • 串行化

事务的传播—7种

如果在事务开始前,一个事务已经存在,此时可以指定该事务的行为

  • PROPAGATION_REQUIRED 如果存在事务,则加入该事务,如果没有,则新建一个。—默认值
  • PROPAGATION_REQUIRES_NEW 创建一个新的,如果有事务,则把当前事务挂起
  • PROPAGATION_SUPPORTS 如果存在事务,则加入该事务,如果没有则以非事务的方式继续
  • PROPAGATION_NOT_SUPPORT 不用事务,如果当前有,则挂起
  • PROPAGATION_NERVER 不用事务,有事务就抛异常
  • PROPAGATION_MANDATORY 如果有则加入,没有就抛异常
  • PROPAGATION_NESTED 如果有就嵌套一个,没有则创建一个

Transactional的失效场景

  • 作用在非public方法上
  • 注解的propagation设置错误(support,notsupport,nerver)
  • rollbackfor设置错误(指定回滚类型)比如自己设置的异常不会回滚
  • 本类方法进行了调用,A没有事务注解,B有,A调用了B,外部方法调用了A(与传播机制有关)
  • 自己在方法内catch了异常
  • 数据库引擎不支持事务

谈谈对springMVC的理解

对servlet进行了封装,屏蔽掉很多的细节。mvc的一个过程
20211011184813

  1. 用户发送请求给DispatcherServlet
  2. 向HandlerMapping索要对应的请求处理器
  3. HandlerMapping返回给相应的处理器
  4. DispatcherServlet给HandlerAdpater传入一个handler
  5. 适配器返回一个能够处理该请求的适配器
  6. 利用该适配器去处理并得到ModelAndView视图对象
  7. 返回给DispatcherServlet视图对象
  8. 使用ViewRouter进行视图解析
  9. ViewRouter返回给view对象
  10. DispatcherServlet渲染视图,将视图呈现给用户

BeanDefinition

CLASS定义了这个类有哪些属性方法,但没有定义如何实例化这个bean,比如是否单例,是否延迟加载,调用哪个初始化/销毁方法

spring如何处理线程并发问题?

一般情况下,只有无状态的bean才可以在多线程环境下共享,在spring中,绝大部分bean都可以声明为singleton(单例)作用域,因为spring对一些bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。

ThreadLocal线程同步机制都是为了解决多线程中共享变量的访问冲突问题。同步机制采用了时间换空间的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的则需要进行排队。、

而ThreadLocal采用了空间换时间的方式ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程编码时,可以把不安全的变量封装进ThreadLocal中

能讲讲spring的生命周期吗

一般对象的生命周期:new创建 — JVM回收

spirng的生命周期如下图

springbean

容器创建过程描述

  1. spring对bean进行实例化
  2. 将值和引用注入到bean所对应的属性中
  3. Spring将bean的ID传递给setBean-Name()
  4. 如果bean实现了BeanFactoryAware接口,将调用setBeanFactory()
  5. 调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来
  6. 调用它们的post-ProcessBeforeInitialization()方法
  7. 调用它们的after-PropertiesSet()方法。类似地,如果bean使用initmethod声明了初始化方法,该方法也会被调用
  8. 此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁
  9. 调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用

谈谈对springboot的理解

  • 是spring组件一站式解决方案
  • 简化spring的难度
  • 简化繁杂的配置,采用自动配置,便于开发

谈谈springboot自动配置原理

空降地址

springbootapplication = springbootconfiguration + commentscan + enableautoconfiguration

enableautoconfiguration = import + autoconfigurationpackage

刷新IOC容器,调用getImports方法,将import注解中的组件进行实例化

谈谈开发中常用的@Autowired是怎么发挥作用的

可以见这篇文章

知道@Autowired和@Resource之间的区别吗?

  • @Autowired是spring提供的,@Resource是Java提供的
  • @Autowired按类型装配,@Resource按名称装配

谈谈对springcloud的理解

为什么会出现?
不管商业还是用户,在业务初期都很简单,我们通常会将他们实现为单体应用。随着业务的逐渐发展,产品也会越来越复杂,单体结构也会越来越复杂,会带来很多问题比如
代码结构混乱(代码多了),导致管理困难
开发困难,开发人员需要不断解决冲突问题,降低开发效率
排查成本高,修bug上线,需要重新编译打包,成本很高
等等的问题表示单体结构逐渐不适应开发,微服务架构逐渐开始取代单体架构,而springcloud是目前最常用的微服务架构框架,已经在企业级开发中大量应用
什么是springcloud?
是一个框架的集合,简化了分布式系统基础设施的开发。有
注册中心,配置中心,路由,服务调用,熔断器等,都可以利用springboot风格做到一键启动和部署
目标:协调各个微服务,简化分布式系统开发

spring推出的一套微服务解决方案,对其中出现的基础场景做出了规范。在这套标准中,spring集成了了Netflix公司的OSS开源套件,比如Eureka、Zuul(网关)、Ribbon(负载均衡)、Hystrix(服务熔断),但随着OSS的停止维护,spring官方也自研了一些组件,另外阿里也整合了spring的标准同时加入自身技术,成了另一套解决方案spring cloud alibaba,其中包括dubbo(RPC通信)、Nacos(注册中心)、sentinel(降级限流)等等

各个组件及其作用

注册中心

  • 用来监控各个微服务是否能正常运行
  • 奈飞的Eureka,阿里巴巴的Nacos
  • 自我保护机制:server在一定时间没有收到client的心跳便会提出服务,如果丢失了大量的心态,就会进入自我保护机制,因为可能出现了网络延迟问题,客户端还正常

服务调用

  • feign:在此实现下,只需创建一个接口并使用注解来配置即可(内置ribbon)
  • openFeign:在feign基础上支持SpringMVC的注解,通过动态代理实现负载均衡调用其他服务
  • ribbon:客户端的负载均衡工具

服务降级

  • 服务雪崩:微服务调用时间长或不可用,会引起系统崩溃,如果还调用了别的模块,就会发生级联故障,或者叫雪崩
  • Hystrix:降级熔断限流,向调用方返回一个符合预期,可处理的备选响应,而不是长时间的等待或抛出无法处理的异常,这样就避免了故障的蔓延,导致雪崩

服务网关

  • gateway:代替zuul,基于webflux框架实现,而webflux底层使用的是通信框架Netty(异步非阻塞)
    可以进行反向代理、鉴权、流量控制、熔断,日志监控

Nacos

  • 注册中心 + 配置中心

sentinel

  • hystrix的阿里版
  • 相较于hystrix,sentinel可以作为一个组件独立出来,可以细粒度进行统一配置

熔断器的过程

  1. 到达一定阈值(默认10秒超过20个请求)
  2. 到达一定失败率(20个请求10个失败)
  3. 断路器开启,所有请求将不会转发
  4. 一段时间后(默认5秒),先放一个请求,如果成功,断路器关闭,如果失败,则继续开启

扩展

更多内容可点击参照这篇文章