Spring总结

Spring总结

1. 什么是 Spring 框架?

Spring 是个java企业级应用的开源开发框架,提供多种特性使得 web 应用开发变得更简便,包括依赖注入、数据绑定、切面编程、数据存取等等。

2. 列举⼀些重要的Spring模块?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cz6JcOQ9-1676627935699)(D:\我的学习资料\面试\面试题\总结面试\Spring面试总结.assets\image-20220529093243637.png)]

  • spring core:提供了框架的基本组成部分,包括控制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)功能。
  • spring beans:提供了BeanFactory,是工厂模式的一个经典实现,Spring将管理对象称为Bean。
  • spring context:构建于 core 封装包基础上的 context 封装包,提供了一种框架式的对象访问方法。
  • spring jdbc:提供了一个JDBC的抽象层,消除了烦琐的JDBC编码和数据库厂商特有的错误代码解析, 用于简化JDBC。
  • spring aop:提供了面向切面的编程实现,让你可以自定义拦截器、切点等。
  • spring Web:提供了针对 Web 开发的集成特性,例如文件上传,利用 servlet listeners 进行 ioc 容器初始化和针对 Web 的 ApplicationContext。
  • spring test:主要为测试提供支持的,支持使用JUnit或TestNG对Spring组件进行单元测试和集成测试。

3.谈谈⾃⼰对于 Spring IoC 大的理解

IoC(Inverse of Control:控制反转)是⼀种设计思想,就是 将原本在程序中⼿动创建对象的控制权,交由Spring框架来管理。IoC 容器是Spring ⽤来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。

将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注⼊。这样可以很⼤程度上简化应⽤的开发,提高开发的效率。 IoC 容器就像是⼀个⼯⼚⼀样,当我们需要创建⼀个对象的时候,只需要配置好配置⽂件注解即可,完全不⽤考虑对象是如何被创建出来的。

Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期

4.谈谈⾃⼰对于AOP 的理解

AOP即面向切面编程(Aspect-Oriented Programming),利用 AOP 可以对各个业务逻辑部分的代码进行隔离封装,从而使得

降低各个业务逻辑部分的耦合度,提高程序的可重用性,同时提高了开发的效率,通俗描述:不通过修改源代码方式,在主干功能里面添加新功能并进行封装。

AOP 底层使用动态代理有两种情况动态代理第一种 有接口情况,使用 JDK 动态代理,创建接口实现类代理对象,增强类的方法。第二种 没有接口情况,使用==CGLIB 动态代理==创建子类的代理对象,增强类的方法

当然我们也可以使⽤ AspectJ ,Spring AOP 已经集成了AspectJ ,AspectJ 相⽐于 Spring AOP 功能更加强⼤,但是 Spring AOP 相对来说更简单,如果我们的切⾯⽐᫾少,那么两者性能差异不⼤。但是,当切⾯太多的话,最好选择 AspectJ ,它⽐Spring AOP 快很多AspectJ 是编译时增强,Spring AOP属于运⾏时增强,⽽ 。 Spring AOP 基于代理(Proxying), ⽽ AspectJ Spring AOP 属于运⾏时增强,⽽ AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),

⽽ AspectJ 基于字节码操作(Bytecode Manipulation)。(Bytecode Manipulation)。

5.Spring Bean

1.Spring 中的 bean 的作⽤域有哪些?

singleton : 唯⼀ bean 实例,Spring 中的 bean 默认都是单例的。

prototype : 每次请求都会创建⼀个新的 bean 实例。

request : 每⼀次HTTP请求都会产⽣⼀个新的bean,该bean仅在当前HTTP request内有

效。

session : 每⼀次HTTP请求都会产⽣⼀个新的 bean,该bean仅在当前 HTTP session 内有

效。

global-session: 全局session作⽤域,仅仅在基于portlet的web应⽤中才有意义,Spring5已经没有了。Portlet是能够⽣成语义代码(例如:HTML)⽚段的⼩型Java Web插件。它们基于portlet容器,可以像servlet⼀样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话

2.Spring 中的单例 bean 的线程安全问题了解吗?

⼤部分时候我们并没有在系统中使⽤多线程,所以很少有⼈会关注这个问题。单例 bean 存在线程问题,主要是因为当多个线程操作同⼀个对象的时候,对这个对象的⾮静态成员变量的写操作会存在线程安全问题。

常⻅的有两种解决办法:

  1. 在Bean对象中尽量避免定义可变的成员变量(不太现实)。

  2. 在类中定义⼀个ThreadLocal成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的⼀种⽅式)。

  3. 最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean() 了,所以就可以保证线程安全了。 有状态就是有数据存储功能。 无状态就是不会保存数据。

3.@Component @Bean 的区别是什么?

  1. 作⽤对象不同: @Component 注解作⽤于类,⽽ @Bean 注解作⽤于⽅法。

  2. @Component 通常是通过类路径扫描来⾃动侦测以及⾃动装配到Spring容器中(我们可以使⽤ @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类⾃动装配到Spring 的 bean 容器中)。 @Bean 注解通常是我们在标有该注解的⽅法中定义产⽣这个bean, @Bean 告诉了Spring这是某个类的示例,当我需要⽤它的时候还给我。

  3. @Bean 注解⽐ Component 注解的⾃定义性更强,⽽且很多地⽅我们只能通过 @Bean 注解来注册bean。⽐如当我们引⽤第三⽅库中的类需要装配到 Spring 容器时,则只能通过@Bean 来实现。

4.**将⼀个类声明为Spring的 **bean的注解有哪些?

我们⼀般使⽤ @Autowired 注解⾃动装配 bean,要想把类标识成可⽤于 @Autowired 注解⾃动装配的 bean 的类,采⽤以下注解可实现:

@Component :通⽤的注解,可标注任意类为 Spring 组件。如果⼀个Bean不知道属于哪个层,可以使⽤ @Component 注解标注。

@Repository : 对应持久层即 Dao 层,主要⽤于数据库相关操作。

@Service : 对应服务层,主要涉及⼀些复杂的逻辑,需要⽤到 Dao层。

@Controller : 对应 Spring MVC 控制层,主要⽤户接受⽤户请求并调⽤ Service 层返回数

据给前端⻚⾯。

5.Spring 中的 bean ⽣命周期?

(1)通过构造器创建 bean 实例(无参数构造)

(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

**(**3)把 bean 实例传递 bean 前置处理器的方法 postProcessBeforeInitialization

(4)调用 bean 的初始化的方法(需要进行配置初始化的方法)

(5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization

(6)bean 可以使用了(对象获取到了)

(7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

6 Spring 框架中⽤到了哪些设计模式?

⼯⼚设计模式 : Spring使⽤⼯⼚模式通过 BeanFactory 、 ApplicationContext 创建 bean 对象。

代理设计模式 : Spring AOP 功能的实现。

模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式

单例设计模式 : Spring 中的 Bean 默认都是单例的。包装器设计模式 : 我们的项⽬需要连接多个数据库,⽽且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。

观察者模式**😗* Spring 事件驱动模型就是观察者模式很经典的⼀个应⽤。

适配器模式 :Spring AOP 的增强或通知(Advice)使⽤到了适配器模式、spring MVC 中也是⽤到了适配器模式适配 Controller 。

7.Spring 事务

Spring 管理事务的⽅式有⼏种?

  1. 编程式事务,在代码中硬编码。(不推荐使⽤)

  2. 声明式事务,在配置⽂件中配置(推荐使⽤)

声明式事务⼜分为两种:

  1. 基于XML的声明式事务

  2. 基于注解的声明式事务

Spring 事务中的隔离级别有哪⼏种?

TransactionDefinition 接⼝中定义了五个表示隔离级别的常量:

TransactionDefinition.ISOLATION_DEFAULT: 使⽤后端数据库默认的隔离级别,Mysql默认采⽤的 可重复读隔离级别 Oracle 默认采⽤的 READ_COMMITTED隔离级别.

TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻⽌脏读,但是幻读或不可重复读仍有可能发⽣

TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同⼀字段的多次读取结果都是⼀致的,除⾮数据是被本身事务⾃⼰所修改,可以阻⽌脏读和不可重复读,但幻读仍有可能发⽣。

TransactionDefinition.ISOLATION_SERIALIZABLE: 最⾼的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执⾏,这样事务之间就完全不可能产⽣⼲扰,也就是说,该****级别可以防⽌脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会⽤到该级别。**

总结:

Spring建议的是使用DEFAULT,就是数据库本身的隔离级别,配置好数据库本身的隔离级别,无论在哪个框架中读写数据都不用操心了。而且万一Spring没有把这几种隔离级别实现的很完善,出了问题就麻烦了。

Spring 事务中哪⼏种事务传播⾏为?

REQUIRED(默认):它是Spring里面默认的事务传播行为,也就新当前存在事务就加入到当前事务去执行,如果不存在事务就创建一个事务
REQUIRE_NEW:它不管是否存在事务,它都会新开启一个事务来执行,新老事务相互独立的,外部事务抛出异常,并不会影响内部事务的一个正常提交
NESTED:如果当前存在事务,就嵌套当前事务中去执行,如果当前没有事务,那么就新建一个事务,类似 REQUIRE_NEW这个样一个传播行为
SUPPORTS:表示支持当前当前的事务,如果当前不存在事务,就以非事务的方式去执行
NOT_SUPPORT:表示以非事务的方式来运行,如果当前存在事务,就需要把当前的事务挂起来。
MANDATORY:它是一个强制的事务执行,如果当前不存在事务就抛出一个异常
NEVER:就是以非事务的方式来执行,如果当前存在事务则抛出一个异常

⽀持当前事务的情况:

TransactionDefinition.PROPAGATION_REQUIRED**:** 如果当前存在事务,则加⼊该事务;如果当前没有事务,则创建⼀个新的事务。

TransactionDefinition.PROPAGATION_SUPPORTS**:** 如果当前存在事务,则加⼊该事务;如果当前没有事务,则以⾮事务的⽅式继续运⾏。

TransactionDefinition.PROPAGATION_MANDATORY**:** 如果当前存在事务,则加⼊该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)

不⽀持当前事务的情况:

TransactionDefinition.PROPAGATION_REQUIRES_NEW**:** 创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_NOT_SUPPORTED**:** 以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_NEVER**:** 以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常。

其他情况:

TransactionDefinition.PROPAGATION_NESTED**:** 如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏;如果当前没有事务,则该取值等价于

TransactionDefinition.PROPAGATION_REQUIRED。

@Transactional(rollbackFor = Exception.class)注解了解吗?

我们知道:Exception分为运⾏时异常RuntimeException和⾮运⾏时异常。事务管理对于企业应⽤来说是⾄关重要的,即使出现异常情况,它也可以保证数据的⼀致性。当 @Transactional 注解作⽤于类上时,该类的所有 public ⽅法将都具有该类型的事务属性,同时,我们也可以在⽅法级别使⽤该标注来覆盖类级别的定义。如果类或者⽅法加了这个注解,那么这个类⾥⾯的⽅法抛出异常,就会回滚,数据库⾥⾯的数据也会回滚。在 @Transactional 注解中如果不配置 rollbackFor 属性,那么事物只会在遇到 RuntimeException 的时候才会回滚,加上 rollbackFor=Exception.class ,可以让事物在遇到⾮运⾏时异常时也回滚。

8. @Autowired和@Resouce的区别

Autowired功能虽说非常强大,但是也有些不足之处。比如:比如它跟spring强耦合了,如果换成了JFinal等其他框架,功能就会失效。而@Resource是JSR-250提供的,它是Java标准,绝大部分框架都支持。

除此之外,有些场景使用@Autowired无法满足的要求,改成@Resource却能解决问题。接下来,我们重点看看@Autowired和@Resource的区别。

  • @Autowired默认按byType自动装配,而@Resource默认byName自动装配。
  • @Autowired只包含一个参数:required,表示是否开启自动装配,默认是true。而@Resource包含七个参数,其中最重要的两个参数是:name 和 type。
  • @Autowired如果要使用byName==,需要使用@Qualifier一起配合。==而@Resource如果指定了name,则用byName自动装配,如果指定了type,则用byType自动装配。
  • @Autowired能够用在:构造器、方法、参数、成员变量和注解上,而@Resource能用在:类、成员变量和方法上。
  • @Autowired是spring定义的注解,而@Resource是JSR-250定义的注解,它的包是javax.annotation.Resource。

9. Spring如何处理线程并发问题?

在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean

中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在

访问前需要获取锁,没获得锁的线程则需要排队。而Th readLocal采用了“空间换时间”的方式。

ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没

有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

10.BeanFactory和ApplicationContext有什么区别?

1、BeanFactory不支持国际化,ApplicationContext支持国际化
2、ApplicationContext扩展了资源加载器接口
3、BeanFactory通常以编程的方式被创建,ApplicationContext能以声明的方式创建
4、BeanFactroy采用的是延迟加载形式来注入Bean的,ApplicationContext是在容器启动时,一次性创建了所有的Bean
5、BeanFactory需要手动注册,而ApplicationContext则是自动注册==

Spring 怎么解决循环依赖问题?

为什么三级缓存:

https://cloud.tencent.com/developer/article/1984274?from=article.detail.2019359&areaSource=106000.7&traceId=4H6aidrNy63-Xc9bdPK93

/** Cache of singleton objects: bean name --> bean instance */
//单例对象的cache
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);

/** Cache of singleton factories: bean name --> ObjectFactory */
//单例对象工厂的cache
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
 
/** Cache of early singleton objects: bean name --> bean instance */
//提前暴光的单例对象的Cache
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

这样做有什么好处呢?让我们来分析一下“A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象”这种循环依赖的情况。

A首先完成了初始化的第一步,并且将自己提前曝光到三级缓存singletonFactories中

此时进行初始化的第二步,发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走create流程,B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存singletonObjects(肯定没有,因为A还没初始化完全),尝试二级缓存earlySingletonObjects(也没有),尝试三级缓存singletonFactories,由于A通过ObjectFactory将自己提前曝光了,所以B能够通过ObjectFactory.getObject拿到A对象(虽然A还没有初始化完全,但是总比没有好呀),B拿到A对象后顺利完成了初始化阶段1、2、3,完全初始化之后将自己放入到一级缓存singletonObjects中。此时返回A中,A此时能拿到B的对象顺利完成自己的初始化阶段2、3,最终A也完成了初始化,进去了一级缓存singletonObjects中,而且更加幸运的是,由于B拿到了A的对象引用,所以B现在hold住的A对象完成了初始化。(简单来说,就是spring创造了一个 循环依赖的结束点标识)

怎么样的循环依赖无法处理?
(1)因为加入singletonFactories三级缓存的前提是执行了构造器来创建半成品的对象,所以构造器的循环依赖没法解决。因此,Spring不能解决“A的构造方法中依赖了B的实例对象,同时B的构造方法中依赖了A的实例对象”这类问题了!

(2)spring不支持原型(prototype)bean属性注入循环依赖,不同于构造器注入循环依赖会在创建spring容器context时报错,它会在用户执行代码如context.getBean()时抛出异常。因为对于原型bean,spring容器只有在需要时才会实例化,初始化它。

因为spring容器不缓存prototype类型的bean,使得无法提前暴露出一个创建中的bean。spring容器在获取prototype类型的bean时,如果因为环的存在,检测到当前线程已经正在处理该bean时,就会抛出异常。核心代码

区分 BeanFactory 和 ApplicationContext?

BeanFactoryApplicationContext
它使用懒加载它使用即时加载
它使用语法显式提供资源对象它自己创建和管理资源对象
不支持国际化支持国际化
不支持基于依赖的注解支持基于依赖的注解

BeanFactory和ApplicationContext的优缺点分析:

BeanFactory的优缺点:

  • 优点:应用启动的时候占用资源很少,对资源要求较高的应用,比较有优势;
  • 缺点:运行速度会相对来说慢一些。而且有可能会出现空指针异常的错误,而且通过Bean工厂创建的Bean生命周期会简单一些。

ApplicationContext的优缺点:

  • 优点:所有的Bean在启动的时候都进行了加载,系统运行的速度快;在系统启动的时候,可以发现系统中的配置问题。
  • 缺点:把费时的操作放到系统启动中完成,所有的对象都可以预加载,缺点就是内存占用较大。

AOP的概念

(1)AOP(面向切面编程),利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得
业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
(2)通俗来说,就是不通过修改源代码方式,在主干功能里面添加新功能。

2.2 AOP的底层原理

AOP底层是使用动态代理来实现的,这里有两种情况的动态代理:

① 有接口的情况,使用 JDK 动态代理
创建接口实现类代理对象,增强类的方法。
② 没有接口的情况,使用 CGLIB 动态代理
创建子类的代理对象,增强类的方法。
2.3 AOP的专业术语

① 连接点:类里面可以被增强的方法,这些方法被称为连接点。

② 切入点:实际被真正增强的方法,称为切入点。

③ 通知(增强):(1)实际增强的逻辑部分称为通知(增强)

​ (2)通知有多种类型:前置通知、后置通知、环绕通知、异常通知、最终通知

④ 切面:把通知应用到切入点的过程,称为切面。

2.4 AOP的操作

① Spring 框架一般都是基于 AspectJ 实现 AOP 操作 ,AspectJ 不是 Spring 的组成部分,独立于 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使用,进行 AOP 操作。
② 基于 AspectJ 实现 AOP 操作
(1)基于 xml 配置文件实现
(2)基于注解方式实现

  • ​ 在增强类上面添加注解 @Aspect
  • 在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
  • 在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高
  • 相同的切入点抽取

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xZ3Bv6Gb-1676627935700)(Spring面试总结.assets/image-20220608094729464.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kb4hMxiZ-1676627935701)(Spring面试总结.assets/image-20220608094804723.png)]

③ 在项目中引入 AOP 的相关依赖,主要有:aop、cglib、aspectj、aopalliance等依赖。
④ 切入点表达式
(1)切入点表达式作用:明确对哪个类里面的哪个方法进行增强。
(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] 方法名称 )

SpringMVC总结

**Spring MVC****的工作原理了解嘛?

1.客户端(浏览器)发送请求,请求直接发送到DispatcherServle

2.DispatcherServlet收到请求信息调用HandlerMapping处理器映射器,处理器映射器根据请求url找到具体的**处理器解析请求对应的Handler。**

3.解析到对应的Handler(也就是我们平常说的Controller控制器),开始由HandlerAdapter适配器处理

4.HandlerAdapter会根据Handler来调用真正的处理器来处理请求和执行相对应的业务逻辑。

5.处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是逻辑上的View。

6.ViewResolver会根据逻辑View去查找实际的View。

7.DispatcherServlet把返回的Model传给View(视图渲染)。

8.把View返回给请求者(浏览器)。

9.注解原理是什么?

注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。我们通过反射获取注解时,返回的是

Java运行时生成的动态代理对象。通过代理对象调用自定义注解的方法,会最终调用AnnotationInvocationHandler的invoke方法。该

方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。

SpringBoot总结

1.什么是 Spring Boot?

Spring Boot (Boot 顾名思义,是引导的意思)框架是用于简化 Spring 应用从搭建到开发的过程。应用开箱即用,只要通过一个指令,包括命令行 java -jar 、SpringApplication 应用启动类 、 Spring Boot Maven 插件等,就可以启动应用了。另外,Spring Boot 强调只需要很少的配置文件,所以在开发生产级 Spring 应用中,让开发变得更加高效和简易。目前,Spring Boot 版本是 2.x 版本。

2.Spring Boot 有哪些优点?

Spring Boot 主要有如下优点:

简化Spring初始搭建以及开发过程,在短时间内快速构建项目
SpringBoot集成了大量的常用第三方库,例如Redis、Mongodb、JPA等,编码非常简单
SpringBoot提供了丰富的starter,集成主流的开源产品,只需要少量配置或零配置即可
SpringBoot内嵌了容器,通过简单命令就可以启动

3.为什么要用SpringBoot?

为了解决java开发中的,繁多的配置、底下的开发效率,复杂的部署流程,和第三方技术集成难度大的问题,产生了SpringBoot。
SpringBoot 使用 “习惯优于配置”的理念让项目快速运行起来,使用SpringBoot很容易创建一个独立运行的jar,内嵌servlet容器
SpringBoot的核心功能一:独立运行Spring项目,SpringBoot可以以jar包的形式独立运行,运行一个SpringBoot项目只需要 java -jar xxx.jar 来运行
SpringBoot的核心功能二:内嵌servlet容器,可以内嵌tomcat,接天jetty,或者undertow,这样我们就可以不用war包形式部署项目
SpringBoot的核心功能三,提供starter简化maven配置,spring提供了一系列starter pom 来简化maven的依赖加载, 当使用了 spring-boot-starter-web时,会自动加载所需要的依赖包
SpringBoot的核心功能四:自动配置spring,springboot 会根据在类路径的jar包,类,为jar包 识别你吗 中的类自动配置bean,这样会极大的减少使用的配置,会根据启动类所在的目录,自动配置bean

4.Spring SpringBoot 有什么不同?

Spring 框架提供多种特性使得 web 应用开发变得更简便,包括依赖注入、数据绑定、切面编程、数据存取等等。

随着时间推移,Spring 生态变得越来越复杂了,并且应用程序所必须的配置文件也令人觉得可怕。这就是 Spirng Boot 派上用场的地方了 – 它使得 Spring 的配置变得更轻而易举。

**5.**如何重新加载Spring Boot 上的更改,而无需重新启动服务器?

这可以使用 DEV 工具来实现。通过这种依赖关系,开发人员可以重新加载 Spring Boot 上的更改,而无需重新启动服务器,嵌入式tomcat 将重

新启动。Spring Boot 有一个开发工具(DevTools)模块,它有助于提高开发人员的生产力。

6.Spring Boot 自动配置原理是什么

Spring启动的时候会扫描所有jar路径下的META-INF/spring.factories,将其文件包装成Properties对象

从Properties对象获取到key值为EnableAutoConfiguration的数据,然后添加到容器里

边。

7.什么是 CSRF 攻击?

CSRF 代表跨站请求伪造。这是一种攻击,迫使最终用户在当前通过身份验证的Web 应用程序上执行不需要的操作。CSRF 攻击专门针对状态改变请

求,而不是数据窃取,因为攻击者无法查看对伪造请求的响应。

8.如何使用 Spring Boot 实现异常处理?

SpringBoot中,@ControllerAdvice 即可开启全局异常处理,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用==@ExceptionHandler注解==然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。

9.Spring Boot 中的监视器是什么?

Spring Boot 中的监视器主要是指Spring boot actuator ,它是是 spring 启动框架中的重要功能之一。Spring boot actuator可帮助访问生产环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为HTTP URL 访问的REST 端点来检查状态。

比如?beans描述应用程序上下文里全部的Bean,以及它们的关系,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KBok10ZJ-1676627935701)(D:\我的学习资料\面试\面试题\总结面试\Spring面试总结.assets\image-20220529164346983.png)]

如何在 Spring Boot 中禁用 Actuator 端点安全性?

默认情况下,所有敏感的 HTTP 端点都是安全的,只有具有 ACTUATOR 角色的用户才能访问它们。安全性是使用标准的

HttpServletRequest.isUserInRole 方法实施的。 我们可以使用来禁用安全性。只有在执行机构端点在防火墙后访问时,才建议禁用安全性。

10.开发 RESTful Web 服务常⽤的注解有哪些?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UoTbLNIA-1676627935701)(D:\我的学习资料\面试\面试题\总结面试\Spring面试总结.assets\image-20220529170438094.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dosr8xno-1676627935702)(D:\我的学习资料\面试\面试题\总结面试\Spring面试总结.assets\image-20220529170628013.png)]

11.Spring Boot 配置加载顺序

**1、**开发者工具 Devtools 全局配置参数;

2、单元测试上的 @TestPropertySource 注解指定的参数;

3、单元测试上的 @SpringBootTest 注解指定的参数;

4、**命令行指定的参数,**如 java -jar springboot.jar --name=“Java程序鱼”;

5、命令行中的 SPRING_APPLICATION_JSONJSON 指定参数, 如 java -Dspring.application.json=‘{“name”:“Java技术栈”}’ -jar springboot.jar

6、ServletConfig 初始化参数;

7、ServletContext 初始化参数;

8、JNDI参数(如 java:comp/env/spring.application.json);

9、Java系统参数(来源:System.getProperties());

10、操作系统环境变量参数;

11、RandomValuePropertySource 随机数,仅匹配:ramdom.*;

12、JAR包外面的配置文件参数(application-{profile}.properties(YAML))

13、JAR包里面的配置文件参数(application-{profile}.properties(YAML))

14、JAR包外面的配置文件参数(application.properties(YAML))

15、JAR包里面的配置文件参数(application.properties(YAML))

16、@Configuration配置文件上 @PropertySource 注解加载的参数;

17、默认参数(通过 SpringApplication.setDefaultProperties 指定);

12.什么是 YAML?

YAML 是一种可读的数据序列化语言。它通常用于配置文件。与属性文件相比,如果我们想要在配置文件中添加复杂的属性,YAML 文件就更加结构化,而且更少混淆。可以看出 YAML 具有分层配置数据。

13.YAML 配置的优势

YAML 现在可以算是非常流行的一种配置文件格式了,无论是前端还是后端,都可以见到 YAML 配置。那么 YAML 配置和传统的 properties 配置相比到底有哪些优势呢?

配置有序,在一些特殊的场景下,配置有序很关键
支持数组,数组中的元素可以是基本数据类型也可以是对象
简洁
相比 properties 配置文件,YAML 还有一个缺点,就是不支持 @PropertySource 注解导入自定义的 YAML 配置。

14. SpringBoot项目在启动时发生了什么?

SpringBoot 项目在启动时,

首先基于启动入口类上的注解描述,进行自动配置并扫描指定包以及子包中的类进行加载,然后检测类上是否有Spring框架中指定的注解描述(例如@Component,@Controller,@Service 等)。假如有,则将类交给Spring框架中的BeanFactory工厂接口的实现类对象,此工厂对象会基于反基于反射创建Bean的实例假如指定了生命周期方法,还会调用生命周期方法。当实例创建以后,Spring框架还会基于类的作用域描述,将实例存储到不同作用域的容器中。以实现Bean对象的科学应用。@ComponentScan是先于@AutoConfigurationPackage 进行检索。

@Controller/@Service/@Component/@Repository这些注解是由ComponentScan来扫描并加载的。

除此之外,还有一些Spring Data注解 比如说,你用了Spring Data JPA,可能会在实体类上写@Entity注解。这个@Entity注解由@AutoConfigurationPackage扫描并加载。

简单理解:这二者扫描的对象是不一样的。

总结

所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8yIfyWJZ-1676627935702)(Spring面试总结.assets/image-20230110162813800.png)]

15.详解面试官经常问的SpringBoot启动流程机制

SpringBoot应用程序的启动流程主要包括初始化SpringApplication和运行SpringApplication两个过程。

其中初始化SpringApplication包括配置基本的环境变量、资源、构造器和监听器,为运行SpringApplciation实例对象作准备;

而运行SpringApplication实例为应用程序正式启动加载过程,包括SpringApplicationRunListeners 引用启动监控模块、ConfigrableEnvironment配置环境模块和监听及ConfigrableApplicationContext配置应用上下文。当完成刷新应用的上下文和调用SpringApplicationRunListener#contextPrepared方法后表示SpringBoot应用程序已经启动完成。

Spring Cloud总结

一、概述

1.1 为什么需要学习Spring Cloud

不论是商业应用还是用户应用,在业务初期都很简单,我们通常会把它实现为单体结构的应用。但是,随着业务逐渐发展,产品思想会变得越来越复杂,单体结构的应用也会越来越复杂。这就会给应用带来如下的几个问题:

  • 代码结构混乱:业务复杂,导致代码量很大,管理会越来越困难。同时,这也会给业务的快速迭代带来巨大挑战;

  • 开发效率变低:开发人员同时开发一套代码,很难避免代码冲突。开发过程会伴随着不断解决冲突的过程,这会严重的影响开发效率;

  • 排查解决问题成本高:线上业务发现 bug,修复 bug 的过程可能很简单。但是,由于只有一套代码,需要重新编译、打包、上线,成本很高。

由于单体结构的应用随着系统复杂度的增高,会暴露出各种各样的问题。近些年来,微服务架构逐渐取代了单体架构,且这种趋势将会越来越流行。Spring Cloud是目前最常用的微服务开发框架,已经在企业级开发中大量的应用。

1.2 Spring Cloud优缺点

微服务的框架那么多比如:dubbo、Kubernetes,为什么就要使用Spring Cloud的呢?

优点:

  • 产出于Spring大家族,Spring在企业级开发框架中无人能敌,来头很大,可以保证后续的更新、完善
  • 组件丰富,功能齐全。Spring Cloud 为微服务架构提供了非常完整的支持。例如、配置管理、服务发现、断路器、微服务网关等;
  • Spring Cloud 社区活跃度很高,教程很丰富,遇到问题很容易找到解决方案
  • 服务拆分粒度更细,耦合度比较低,有利于资源重复利用,有利于提高开发效率
  • 可以更精准的制定优化服务方案,提高系统的可维护性
  • 减轻团队的成本,可以并行开发,不用关注其他人怎么开发,先关注自己的开发
  • 微服务可以是跨平台的,可以用任何一种语言开发
  • 适于互联网时代,产品迭代周期更短

缺点:

  • 微服务过多,治理成本高,不利于维护系统
  • 分布式系统开发的成本高(容错,分布式事务等)对团队挑战大
  • 总的来说优点大过于缺点,目前看来Spring Cloud是一套非常完善的分布式框架,目前很多企业开始用
  • 微服务、Spring Cloud的优势是显而易见的。因此对于想研究微服务架构的同学来说,学习SpringCloud是一个不错的选择。

二、主要项目

Spring Cloud的子项目,大致可分成两类,一类是对现有成熟框架"Spring Boot化"的封装和抽象,也是
数量最多的项目;第二类是开发了一部分分布式系统的基础设施的实现,如Spring Cloud Stream扮演
的就是kafka, ActiveMQ这样的角色。

2.1 Spring Cloud Config

集中配置管理工具,分布式系统中统一的外部配置管理,默认使用Git来存储配置,可以支持客户端配置的刷新及加密、解密操作。

2.2 Spring Cloud Netflix

Netflix OSS 开源组件集成,包括Eureka、Hystrix、Ribbon、Feign、Zuul等核心组件。
Eureka:服务治理组件,包括服务端的注册中心和客户端的服务发现机制;
Ribbon:负载均衡的服务调用组件,具有多种负载均衡调用策略;
Hystrix:服务容错组件,实现了断路器模式,为依赖服务的出错和延迟提供了容错能力;
Feign:基于Ribbon和Hystrix的声明式服务调用组件;
Zuul:API网关组件,对请求提供路由及过滤功能。

2.3 Spring Cloud Bus

用于传播集群状态变化的消息总线,使用轻量级消息代理链接分布式系统中的节点,可以用来动态刷新
集群中的服务配置。

2.4 Spring Cloud Consul

基于Hashicorp Consul的服务治理组件。

2.5 Spring Cloud Security

安全工具包,对Zuul代理中的负载均衡OAuth2客户端及登录认证进行支持。

2.6 Spring Cloud Sleuth

Spring Cloud应用程序的分布式请求链路跟踪,支持使用Zipkin、HTrace和基于日志(例如ELK)的跟
踪。

2.7 Spring Cloud Stream

轻量级事件驱动微服务框架,可以使用简单的声明式模型来发送及接收消息,主要实现为Apache Kafka
及RabbitMQ。

2.8 Spring Cloud Task

用于快速构建短暂、有限数据处理任务的微服务框架,用于向应用中添加功能性和非功能性的特性。

2.9 Spring Cloud Zookeeper

基于Apache Zookeeper的服务治理组件。

2.10 Spring Cloud Gateway

API网关组件,对请求提供路由及过滤功能。

2.11 Spring Cloud OpenFeign

基于Ribbon和Hystrix的声明式服务调用组件,可以动态创建基于Spring MVC注解的接口实现用于服务
调用,在Spring Cloud 2.0中已经取代Feign成为了一等公民。

三、其他

3.1 SpringBoot和SpringCloud的区别?

SpringBoot专注于快速方便的开发单个个体微服务。

SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务

SpringBoot可以离开SpringCloud独立使用开发项目, 但是SpringCloud离不开SpringBoot ,属于依赖的关系SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。

3.2 使用 Spring Boot 开发分布式微服务时,我们面临以下问题

(1)与分布式系统相关的复杂性-这种开销包括网络问题,延迟开销,带宽问题,安全问题。

(2)服务发现-服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉及一个服务目录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。
(3)冗余-分布式系统中的冗余问题。

(4)负载平衡 --负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机集群,网络链路,中央处理单元,或磁盘驱动器的分布。

(5)性能-问题 由于各种运营开销导致的性能问题。

(6)部署复杂性-Devops 技能的要求。

3.3 服务注册和发现是什么意思?Spring Cloud 如何实现?

当我们开始一个项目时,我们通常在属性文件中进行所有的配置。随着越来越多的服务开发和部署,添加和修改这些属性变得更加复杂。有些服务可能会下降,而某些位置可能会发生变化。手动更改属性可能会产生问题。 Eureka 服务注册和发现可以在这种情况下提供帮助。由于所有服务都在 Eureka 服务器上注册并通过调用 Eureka 服务器完成查找,因此无需处理服务地点的任何更改和处理。

3.4 Spring Cloud 和dubbo区别?

(1)服务调用方式 dubbo是RPC springcloud Rest Api
(2)注册中心,dubbo 是zookeeper springcloud是eureka,也可以是zookeeper
(3)服务网关,dubbo本身没有实现,只能通过其他第三方技术整合,springcloud有Zuul路由网关,作
为路由服务器,进行消费者的请求分发,springcloud支持断路器,与git完美集成配置文件支持版本控
制,事物总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素。

3.5 负载平衡的意义什么?

在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。

3.6 什么是 Hystrix?它如何实现容错?

Hystrix 是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当出现故障是不可避免的
故障时,停止级联故障并在复杂的分布式系统中实现弹性。
通常对于使用微服务架构开发的系统,涉及到许多微服务。这些微服务彼此协作。

思考以下微服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bMhb5bDr-1676627935702)(Spring面试总结.assets/image-20230111113545325.png)]

假设如果上图中的微服务 9 失败了,那么使用传统方法我们将传播一个异常。但这仍然会导致整个系统崩溃。
随着微服务数量的增加,这个问题变得更加复杂。微服务的数量可以高达 1000.这是 hystrix 出现的地方我们将使用 Hystrix 在这种情况下的 Fallback 方法功能。我们有两个服务 employee-consumer 使用由employee-consumer 公开的服务。

简化图如下所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nlC6ex5h-1676627935702)(Spring面试总结.assets/image-20230111113639626.png)]

现在假设由于某种原因,employee-producer 公开的服务会抛出异常。我们在这种情况下使用 Hystrix
定义了一个回退方法。这种后备方法应该具有与公开服务相同的返回类型。如果暴露服务中出现异常,
则回退方法将返回一些值。

3.7 什么是 Netflix Feign?它的优点是什么?

Feign 是受到 Retrofit,JAXRS-2.0 和 WebSocket 启发的 java 客户端联编程序。
Feign 的第一个目标是将约束分母的复杂性统一到 http apis,而不考虑其稳定性。
在 employee-consumer 的例子中,我们使用了 employee-producer 使用 REST模板公开的 REST 服
务。
但是我们必须编写大量代码才能执行以下步骤
(1)使用功能区进行负载平衡。
(2)获取服务实例,然后获取基本 URL。
(3)利用 REST 模板来使用服务。 前面的代码如下
之前的代码,有像 NullPointer 这样的例外的机会,并不是最优的。我们将看到如何使用 Netflix Feign
使呼叫变得更加轻松和清洁。如果 Netflix Ribbon 依赖关系也在类路径中,那么 Feign 默认也会负责负
载平衡。

3.8 什么是 Spring Cloud Bus?我们需要它吗?

考虑以下情况:我们有多个应用程序使用 Spring Cloud Config 读取属性,而Spring Cloud Config 从
GIT 读取这些属性。
下面的例子中多个员工生产者模块从 Employee Config Module 获取 Eureka 注册的财产。
@Controller
public class ConsumerControllerClient {
@Autowired
private LoadBalancerClient loadBalancer;
public void getEmployee() throws RestClientException, IOException {
ServiceInstance serviceInstance=loadBalancer.choose(“employee-producer”);
System.out.println(serviceInstance.getUri());
String baseUrl=serviceInstance.getUri().toString();
baseUrl=baseUrl+“/employee”;
RestTemplate restTemplate = new RestTemplate();
ResponseEntity response=null;
try{
response=restTemplate.exchange(baseUrl,
HttpMethod.GET, getHeaders(),String.class);
}
catch (Exception ex)
{
System.out.println(ex);
}
System.out.println(response.getBody());
}

如果假设 GIT 中的 Eureka 注册属性更改为指向另一台 Eureka 服务器,会发生什么情况。在这种情况
下,我们将不得不重新启动服务以获取更新的属性。
还有另一种使用执行器端点/刷新的方式。但是我们将不得不为每个模块单独调用这个 url。例如,如果
Employee Producer1 部署在端口 8080 上,则调用 http:// localhost:8080 / refresh。同样对于
Employee Producer2 http://localhost:8081 / refresh 等等。这又很麻烦。这就是 Spring Cloud
Bus 发挥作用的地方。
Spring Cloud Bus 提供了跨多个实例刷新配置的功能。因此,在上面的示例中,如果我们刷新
Employee Producer1,则会自动刷新所有其他必需的模块。如果我们有多个微服务启动并运行,这特
别有用。这是通过将所有微服务连接到单个消息代理来实现的。无论何时刷新实例,此事件都会订阅到
侦听此代理的所有微服务,并且它们也会刷新。可以通过使用端点/总线/刷新来实现对任何单个实例的
刷新。

3.9 Spring Cloud断路器的作用

当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应 当更多
的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应)
断路器有完全打开状态:一段时间内 达到一定的次数无法调用 并且多次监测没有恢复的迹象 断路器完全
打开 那么下次请求就不会请求到该服务
半开:短时间内 有恢复迹象 断路器会将部分请求发给该服务,正常调用时 断路器关闭
关闭:当服务一直处于正常状态 能正常调用

3.10 什么是Spring Cloud Config?

在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配
置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配
置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角
色,一是config server,二是config client。
使用:
(1)添加pom依赖
102
公众号:Java旅途
(2)配置文件添加相关配置
(3)启动类添加注解@EnableConfigServer

3.11 什么是Spring Cloud Gateway?

Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,
在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。
使用了一个RouteLocatorBuilder的bean去创建路由,除了创建路由RouteLocatorBuilder可以让你添加
各种predicates和filters,predicates断言的意思,顾名思义就是根据具体的请求的规则,由具体的
route去处理,filters是各种过滤器,用来对请求做各种判断和修改。
崩效应)
断路器有完全打开状态:一段时间内 达到一定的次数无法调用 并且多次监测没有恢复的迹象 断路器完全
打开 那么下次请求就不会请求到该服务
半开:短时间内 有恢复迹象 断路器会将部分请求发给该服务,正常调用时 断路器关闭
关闭:当服务一直处于正常状态 能正常调用

3.10 什么是Spring Cloud Config?

在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配
置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配
置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角
色,一是config server,二是config client。
使用:
(1)添加pom依赖
102
公众号:Java旅途
(2)配置文件添加相关配置
(3)启动类添加注解@EnableConfigServer

3.11 什么是Spring Cloud Gateway?

Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,
在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。
使用了一个RouteLocatorBuilder的bean去创建路由,除了创建路由RouteLocatorBuilder可以让你添加
各种predicates和filters,predicates断言的意思,顾名思义就是根据具体的请求的规则,由具体的
route去处理,filters是各种过滤器,用来对请求做各种判断和修改。
103

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值