SpringBoot八股文
SpringBoot八股文
SpringBoot的项目结构是怎么样的?



说一说Spring框架核心特性有哪些? / 好处有哪些?
-
IOC容器:Spring通过控制反转实现了对象的创建和对象间的依赖关系管理,开发者只需要定义好Bean及其依赖关系,Spring容器就会负责创建和组装这些对象
-
AOP:面向切面编程,允许开发者横切关注点,例如事务管理、安全控制、日志记录等,可以提高代码的可维护度和可重用性
-
事务管理:Spring提供了一致的事务管理接口,支持声明式和编程式事务。开发者可以轻松地进行事务管理,而无需关心具体的事务API

-
MVC框架:Spring MVC是一种Web框架,采用了模型-视图-控制器(MVC)框架,它支持灵活的URL到页面控制器的映射
-
非侵入式设计:它可以使应用程序对框架的依赖最小化
介绍一下IOC
简介:IoC即控制反转的意思,它是一种创建和获取对象的技术思想,依赖注入(DI)是实现这种技术的一种方式。在传统开发过程中,我们需要通过new关键字来创建对象。使用IoC思想开发方式的话,就可以不用new关键字来创建对象,而是通过IoC容器来帮我们完成实例化对象。通过IoC的方式可以大大降低对象之间的耦合度
IOC控制就是对象的创建、初始化、销毁;
- 创建对象:原来是new一个,现在由Spring容器创建;
- 初始化对象:原来是对象自己通过构造器或者setter方法给依赖的对象赋值,现在是由Spring容器自动注入;
- 销毁对象:原来是直接给对象赋值null或做一些销毁操作,现在是Spring容器管理生命周期负责销毁对象
IoC的实现机制
-
反射:Spring IoC容器利用Java的反射机制动态的加载类信息、创建对象实例以及调用对象方法,反射允许在运行时检查类、方法、属性等信息,有利于灵活的实现对象实例化和管理
-
依赖注入:IOC的核心概念是依赖注入,也就是容器负责应用程序组件之间的依赖关系。Spring通过构造方法注入、属性注入、方法注入,将组件之间的依赖关系描述在配置文件中或使用注解
-
设计模式-工厂模式:Spring IOC容器通常使用工厂模式来管理对象的创建和生命周期;容器作为工厂负责实例化Bean并管理它们的生命周期,将Bean的实例化过程交给容器来管理
-
容器实现:Spring IOC容器是实现IOC的核心,通常使用BeanFactory或ApplicationContext来管理Bean。BeanFactory是IOC容器的基本形式,提供基本的IOC功能;ApplicationContext是BeanFactory的扩展,并提供更多企业级功能
什么是Bean?
-
Bean是对象,一个或者多个不限定
-
Bean托管在Spring中一个叫IoC的容器中
-
我们的程序是由一个个Bean构成的
什么是FactoryBean?
-
FactoryBean是Spring所提供的一种比较灵活的创建Bean的方式,可以通过实现FactoryBean接口中的getObject()方法来返回一个对象,这个对象就是最终的Bean对象;
-
如果一个对象实现了这个接口,那么它就成为一种特殊的Bean,注册到IoC容器后,如果调用这个对象的 getBean 获得的是 FactoryBean

- 为什么要有FactoryBean呢? FactoryBean机制被广泛的应用在Spring内部和Spring与第三方框架或组件的整合过程中;假设依赖一个第三方类A,创建这个类的对象比较复杂,同时我们想设置这个类中的某些属性,但是这个类没有提供设置的方法,就可以用一个Bean来封装它


说一说BeanFactory和ApplicationContext


-
BeanFactory是一个接口,里面定义了getBean()这一个方法,通过实现这个方法可以得到Bean;而ApplicationContext它实现了BeanFactory的实现接口,也属于一个BeanFactory,在ApplicationContext中扩展了很多其他功能,AOP、国际化、资源管理、事件、注解等
-
BeanFactory的优缺点
-
优点:应用启动时占用资源很少
-
缺点:运行速度相对来说慢一点,有可能出现空指针异常的错误
-
-
ApplicationContext的优缺点
-
优点:所有的Bean在启动的时候都进行了加载,系统运行的速度快
-
缺点:把费时的操作放到系统启动中完成,所有的对象都可以预加载,会导致内存占用大
-
介绍一下DI
介绍一下AOP
-
简介:AOP是面向切面编程,允许开发者横切关注点,例如事务管理、安全控制、日志记录等,可以提高代码的可维护度和可重用性
-
在面向切面编程的思想里面,把功能分为两种,一种是核心业务,比如登陆、注册、增、删、改、查都叫核心业务;另一种是周边功能,比如日志、事务管理这些次要的就是周边业务;在面向切面编程中,核心业务功能和周边功能是分别独立进行开发,两者不是耦合的,通过AOP可以将核心业务和周边功能“编织”在一起,这样可以减少系统的重复代码,降低模块之间的耦合度,有利于未来的可拓展性和可维护性
-
AOP实现机制
-
Spring AOP的实现依赖于动态代理技术。动态代理是在运行时动态生成代理对象,对不是编译时。它允许开发者在运行时指定要代理的接口和行为,从而实现在不修改源码的情况下增强方法的功能。
-
基于JDK的动态代理:使用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口实现。这种方式需要代理的类实现一个或多个接口
-
基于CGLIB的动态代理:当被代理的类没有实现接口时,Spring会使用CGLIB库生成一个被代理的子类作为代理,CGLIB(Code Generation Library)是一个第三方代码生产库,通过继承方式实现代理
-

动态代理
动态代理是什么?
一种在运行时动态创建代理对象的机制,主要用于在不修改原始类的情况下对方法调用进行拦截和增强
-
基于接口的代理(JDK动态代理):这种类型的代理要求目标对象必须实现至少一个接口。Java动态代理会创建一个实现了相同接口的代理类,然后在运行时动态生成该类的实例。
-
基于类的代理(CGLIB动态代理):是一个强大的高性能的代码生成库,它可以在运行时动态生成一个目标类的子类。CGLIB代理不需要目标类实现接口,而是通过继承的方式创建代理类。因此,如果目标对象没有实现任何接口,可以使用CGLIB来创建动态代理
动态代理和静态代理的区别?
代理是一种常用的设计模式,目的是:为其他对象提供一个代理以控制对某个对象的访问,将两个类的关系解耦。代理类和委托类都要实现相同的接口,因为代理真正调用的是委托类的方法
-
静态代理:由程序员创建或者是由特定工具创建,在代码编译时就确定了被代理的类是一个静态代理。静态代理通常只代理一个类;
-
动态代理:在代码运行期间,运用反射机制动态创建生成。动态代理代理的是一个接口下的多个实现类。
能用静态代理的方式实现AOP吗?
可行的,但是在实际生产中基本没有人使用,因为有三大硬伤
-
第一是代码爆炸:如果有100个Service类需要加事务,就需要写100个重复的try-catch提交回滚代码,维护起来很困难
-
第二是僵化:一旦给业务接口改了个方法名,所有相关的代理类都得跟着改方法名
-
第三是无法动态筛选:比如你想只给带 @Transactional 注解的方法加事务,静态代理只能写死逻辑,要在实现的方法中判断 Transactional.class,而 Spring AOP 可以在运行时通过切点表达式精准匹配需要增强的方法
反射
-
反射指的是在程序运行状态下,对于任意一个类,都可以知道这个类的所有属性和方法,都能调用它的所有属性和方法,Java的反射机制允许在运行时获取类的信息并动态操作对象,即使在编译时不知道具体的类也能实现
-
反射有以下几个特性
-
运行时类信息方法:反射允许程序在运行时获取类的所有信息,属性、方法
-
动态对象创建:可以使用反射API,Class类的newInstance()方法,动态的创建对象实例,即使在编译时不知道具体的类名
-
动态方法调用:通过Method类的invoke()方法可以在运行时动态调用对象的方法,包括私有方法
-
访问和修改字段值:通过Field类的get()和set()方法可以在程序运行时访问和修改对象的字段值,即使是私有的
- Spring框架的依赖注入(DI)和控制反转(IoC)
-
依赖注入(DI):在Spring中,程序员可以通过XML配置文件或者基于注解的方式声明组件之间的依赖关系,当程序运行启动时,Spring容器会扫描这些配置或注解,然后利用反射来实例化Bean(也就是Java对象),并根据配置自动状态它们的依赖
-
控制反转(IoC):当一个Service类需要依赖另一个DAO类,程序员可以在Service类中使用@Autowired注解,无需自己编写DAO实例的代码,Spring容器在运行解析这个注解,通过反射找到对应的DAO类,实例化它并管理它,将其注入到Service类中。降低了组件之间的耦合度,增强可维护性
- 动态代理中反射的应用
为了给所有服务处方法添加日志记录功能,Spring会使用JDK动态代理或CGLIB(如果目标类没有实现接口的话)来创建目标类的代理对象。这个代理对象在调用任何方法的前或后,都会执行记录日志的逻辑,这一切都是在运行时通过反射来动态构建和执行的,无需编码到每个方法调用中。
依赖倒置,依赖注入,控制反转分别是什么?
-
控制反转:“控制”指的是对程序的执行流程控制,而“反转”指的是在没有使用框架之前,程序员自己控制整个程序的执行。在使用框架后,整个程序的执行流程交给框架,程序的控制权由程序员交给了框架
-
依赖注入:我们不通过new的方式在类内部创建依赖类的对象,而是将依赖类的对象在外部创建好后,通过构造函数、函数参数等方式传递给类使用
以下是几种注入的方式
-
构造器注入

-
Setter方法注入

-
字段注入

- 依赖倒置:高层模块(高管)不依赖底层模块(员工),它们共同依赖同一个抽象类,可以类似于一种设计模式的设计指南,目的都是为了“解耦”

Spring时如何解决循环依赖的?
什么是循环依赖?
循环依赖指的是两个类中的属性相互依赖对方:例如A类中有B属性,B类中有A属性,从而形成了一个依赖闭环,如下图
- 相互依赖

- 三者之间及其以上的依赖

- 自我依赖

循环依赖问题在Spring中的三种主要情况
- 第一种:通过构造方法进行依赖注入时产生的循环依赖问题
1 | // Bean A,构造方法依赖 B |
- 第二种:通过setter方法(使用了@Scope注解)进行依赖注入且是在多例(原型)模式下产生的循环依赖问题
1 | // 原型 Bean C,Setter 依赖 D |
- 第三种:通过setter方法进行依赖注入且是在单例模式下产生的循环依赖问题
1 | // 原型 Bean E,Setter 依赖 F |
只有【第三种方式】的循环依赖问题被Spring解决了,其他两种方式在遇到循环依赖问题时,Spring都会产生异常
三级缓存
Spring在DefaultSingletonBeanRegistry类中维护了三个重要的缓存(Map),称为“三级缓存”
- singletonObjects(一级缓存):存放的是初始化好的,可以使用的Bean,getBean() 方法返回的也是这里面的Bean,此时Bean已经实例化、属性已经填充、初始化方法已经执行、AOP代理(如果需要的话)也已经生成
交付最终完整的Bean
- earlySingletonObjects(二级缓存):当一个Bean还在创建的过程中(已经实例化了,但尚未完成属性填充和初始化),但它的引用需要被注入到另一个Bean中,就暂时存放到这里
临时存储已确定的早期引用,避免重复生成代理
- singletonFactories(三级缓存):存放的是Bean的ObjectFactory工厂对象,这是解决循环依赖的关键,当一个Bean被实例化后(刚掉完构造函数),Spring会创建一个ObjectFactory并将其放入三级缓存。这个工厂的getObject()方法负责返回该Bean的早期引用
负责在对象实例化后立刻暴露对象的生成能力,兼顾AOP代理的提前生成
- Spring 通过 三级缓存 和 提前暴露未完全初始化的对象引用 的机制来解决【单例作用域 Bean】 的 sette注入方式的循环依赖问题。
Spring解决循环依赖的流程
- 第一步:创建BeanA的实例并提前暴露工厂

Spring首先调用BeanA的构造函数进行实例化,此时得到一个原始对象(没有填充属性),紧接着,Spring会将一个特殊的ObjectFactory工厂对象存入三级缓存(singletonFactories)。这个工厂的作用是,当其他Bean需要引用BeanA时,它能动态返回当前这个半成品BeanA,此时BeanA的状态是“已实例化但未初始化”
- 第二步:填充BeanA的属性时触发BeanB的创建

Spring开始为BeanA注入属性,发现它依赖BeanB。于是容器转向创建BeanB,同样先调用其构造函数实例化,并将BeanB对应的ObjectFactory存入三级缓存。至此,三级缓存中同时存在BeanA和BeanB的工厂,都是未完成品
- 第三步:BeanB属性注入时发现循环依赖
- 定位BeanA在哪

- BeanA的引用存入二级缓存,清理三级缓存

当Spring试图填充BeanB的属性时,检测到它需要注入BeanA,此时容器开始依赖查找:在一级缓存中未找到BeanA,在二级缓存中也未命中,最终在三级缓存中定位到BeanA的工厂;Spring立即调用BeanA的getObject() 方法,这个方法如果需要AOP代理,会动态生成代理对象;如果不需要,直接返回原始对象。得到的BeanA早期引用会被放入二级缓存(earlySingletonObjects),同时从三级缓存清理BeanA的工厂。
- 第四步:完成BeanB的生命周期

BeanB获得所有依赖后,Spring执行其初始化方法,将其转化为可以使用的Bean,随后BeanB被提升至一级缓存,二级缓存、三级缓存由于BeanB的临时数据被清除
- 第五步:回溯完成BeanA的构建

随着BeanB创建完毕,流程回溯到最初中断BeanA属性注入环节。Spring已经具备能将BeanB实例注入BeanA,接着执行BeanA的初始化方法,最终完成初始化的BeanA会进入一级缓存中
Spring为什么用3级缓存解决循环依赖问题?用2级缓存不行吗?
Spring提供了哪些配置方式?
- 基于xml配置
bean所需要的依赖项和服务在XML格式的配置文件中定义,这些配置文件通常包含需要bean定义的配置选项

- 基于注解配置
可以通过在相关的类,方法或字段声明上使用注解,将bean配置为组件类本身,而不是使用XML来描述bean装配。需要在Spring配置文件中启用它

启动之后,可以基于 Java API 配置,Spring的Java配置是通过使用@Bean和@Configuration来实现
-
@Bean注解扮演与
<bean />元素相同的角色 -
@Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义Bean间依赖关系

将一个类声明为Spring的Bean的注解有哪些?
-
我们一般使用 @Autowired 注解自动装配bean,想要把类表示成可用于 @Autowired 注解自动装配的 bean 的类,可以采用以下注解实现
-
@Component:通用的注解,可以标注任意类为Spring组件,如果一个Bean不知道属于哪个层,可以使用@Component注解标注 -
@Repository:对应持久层即Dao层,主要用于数据库相关操作 -
@Service:对应服务层,主要涉及一些复杂的逻辑,需要用到Dao层 -
@Controller:对应Spring MVC控制层,主要用于接收用户请求并调用Service层返回数据给前端页面
Bean一共有几种作用域?
-
singleton:默认是单例,一个 IOC 容器内部仅此一个 -
prototype:原型,多实例 -
request:每个请求都会新建一个属于自己的 Bean 实例,这种作用域仅存在 Spring Web 应用中 -
session:一个 http session 中有一个 bean 的实例,这种作用域仅存在 Spring Web 应用中 -
application:整个 ServletContext 生命周期里,只有一个 bean,这种作用域仅存在 Spring Web 应用中 -
websocket:一个 WebSocket 生命周期内一个 bean 实例,这种作用域仅存在 Spring Web 应用中
Spring中的单例Bean的线程安全问题?
当多个用户同时发送一个请求,容器会给每一个请求分配一个线程,如果这些线程都涉及到对Bean对象的值进行修改,就需要考虑线程同步问题
无状态Bean和有状态Bean
-
无状态就是一次操作,没有可以修改的成员变量,不能保存数据,是线程安全的
-
有状态是数据存储功能,可以保存数据,线程不安全
在Spring中无状态的Bean适合用不变模式,使用单例模式策略,这样可以共享实例提高性能;有状态的Bean,在多线程环境下不安全,使用Prototype原型模式策略;单例Bean但每个线程需要独立数据,使用单例+ThreadLocal策略
Spring中的Bean生命周期?

具体一点

1. 先通过构造器创建 Bean 实例;2. 根据属性,注入需要的 Bean;3. 如果实现了 BeanNameAware 等 aware 接口,就执行 aware 注入;4. 把 bean 实例传递 bean 前置处理器的方法 postProcessBeforeInitialization;5. 调用 bean 的初始化的方法;6. 再把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization;7. 这样 bean 就可以使用了;8. 当容器关闭时候,调用 bean 的销毁的方法
什么是Spring的内部Bean?
只有将 Bean 作用另一个 Bean 的属性时,才能将 Bean 声明为内部 Bean。例如,假设有一个 Student 类,其中引用了 Person 类。代码和配置如下


什么是 Spring 装配?
“装配” 是指 Spring 容器通过依赖注入,将多个 Bean(对象)组合绑定,形成完整业务逻辑单元的过程
举个例子:有 UserService依赖于UserDao,Spring容器通过依赖注入,将UserDao注入到UserService的属性 / 构造器中,让两个Bean形成依赖,这个组合绑定的过程就是Bean装配
自动装配的不同模式
- no:这是默认设置,表示没有自动装配

- byName:它根据bean的名称注入对象依赖项

-
byType:它根据类型注入对象依赖项
-
构造函数:它通过调用类的构造函数来注入依赖项

- autodetect:首先容器会尝试使用构造函数 autowire 装配,如果不行,则尝试通过 byType 自动装配
Spring / SpringBoot框架中用到了哪些设计模式?
-
工厂设计模式:Spring使用工厂模式通过BeanFactory、ApplicationContext创建Bean对象
-
代理设计模式:Spring AOP功能的设计
-
单例设计模式:Spring中的Bean默认都是单例的
-
模板方法模式:Spring中 jdbcTemplate、hibernateTemplate对数据库操作的类,使用了模板模式
-
包装器设计模式:项目需要连接多个数据库,不同用户在每次访问中根据需求回去访问不同的数据库,这种模式可以让我们根据用户的需求能够动态切换不同的数据源
-
观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用
-
适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式
Spring事务有几个隔离级别?
数据库自定义的隔离级别、读未提交、读已提交、可重复度、序列化
Spring有哪几种事务传播行为?
-
PROPAGATION_REQUIRED(默认) 如果当前存在事务,则用当前事务,如果没有事务则新起一个事务
-
PROPAGATION_SUPPORTS 支持当前事务,如果不存在,则以非事务方式执行
-
PROPAGATION_MANDATORY 支持当前事务,如果不存在,则抛出异常
-
PROPAGATION_REQUIRES_NEW 创建一个新事务,如果存在当前事务,则挂起当前事务
-
PROPAGATION_NOT_SUPPORTED 不支持当前事务,始终以非事务方式执行
-
PROPAGATION_NEVER 不支持当前事务,如果当前存在事务,则抛出异常
-
PROPAGATION_NESTED 如果当前事务存在,则在嵌套事务中执行,内层事务依赖外层事务,如果外层失败,则会回滚内层,内层失败不影响外层。
Spring MVC工作原理是什么?

-
客户端发送请求到 DispatcherServlet
-
DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler
-
解析到对应的Handler(也就是常说的Controller层),开始由HandlerAdapter适配器处理
-
HandlerAdapter会根据Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑
-
处理完请求后,会返回一个ModelAndView对象,Model是返回的数据对象,View是这个逻辑上的View
-
ViewResolver会根据逻辑View查找实际的View
-
DispaterServlet会把返回的Model传给View(视图渲染)
-
最后,将View返回给客户端
@Controller注解有什么用?
@Controller 注解标记一个类为 Spring Web MVC 控制器 Controller。Spring MVC 会将扫描到该注解的类,然后扫描这个类下面带有 @RequestMapping 注解的方法,根据注解信息,为这个方法生成一个对应的处理器对象。
@RequestMapping 注解有什么用?
@RequestMapping 注解,配置处理器的 HTTP 请求方法,URI等信息,这样才能将请求和方法进行映射。这个注解可以作用于类上面,也可以作用于方法上面,在类上面一般是配置这个控制器的 URI 前缀
@RestController 和 @Controller 有什么区别?
@RestController 注解,在 @Controller 基础上,增加了 @ResponseBody 注解,更加适合目前前后端分离的架构下,提供 Restful API ,返回例如 JSON 数据格式。当然,返回什么样的数据格式,根据客户端的 ACCEPT 请求头来决定。
- @Controller

- @RestController

@RequestMapping 和 @GetMapping 注解的不同之处在哪里?
-
@RequestMapping:可注解在类和方法上;@GetMapping 仅可注册在方法上
-
@RequestMapping:可进行 GET、POST、PUT、DELETE 等请求方法;
-
@GetMapping 是 @RequestMapping 的 GET 请求方法的特例,目的是为了提高清晰度。
@RequestParam 和 @PathVariable 两个注解的区别
两个注解都用于方法参数,获取参数值的方式不同,@RequestParam 注解的参数从请求携带的参数中获取,而 @PathVariable 注解从请求的 URI 中获取
返回 JSON 格式使用什么注解?
可以使用 @ResponseBody 注解,或者使用包含 @ResponseBody 注解的 @RestController 注解。
当然,还是需要配合相应的支持 JSON 格式化的 HttpMessageConverter 实现类。例如,Spring MVC 默认使用 MappingJackson2HttpMessageConverter。
Spring Boot
为什么使用springboot?/ 比spring好在哪里?
-
简化开发:SpringBoot通过提供一系列的开箱即用的组件和自动配置,简化了项目的配置和开发过程,开发人员可以更专注于业务逻辑实现,而不需要花费过多时间在繁琐的配置上
-
快速启动:Spring Boot提供了快速的应用程序启动方式,可通过内嵌的Tomcat、Jetty或Undertow等容器快速启动应用程序,无需额外的部署步骤,方便快捷。
-
自动化配置:Spring Boot通过自动配置功能,根据项目中的依赖关系和约定俗成的规则来配置应用程序,减少了配置的复杂性,使开发者更容易实现应用的最佳实践。
怎么理解SpringBoot中的约定大于配置?
约定大于配置是SpringBoot的核心设计理念,它通过预期合理的默认行为和项目规范,大幅减少开发者需要手动配置的步骤,从而提升开发效率和项目标准化程度
理解约定大于配置,可以从以下几个方面来解释
-
自动化配置:Spring Boot 提供了大量的自动化配置,通过分析项目的依赖和环境,自动配置应用程序的行为。开发者无需配置每个细节,大部分常用的配置都已经预设好了。例如,引入spring-boot-starter-web后,Spring Boot会自动配置内嵌Tomcat和Spring MVC,无需手动编写XML。
-
默认配置:Spring Boot 为诸多方面提供大量默认配置,如连接数据库、设置 Web 服务器、处理日志等。开发人员无需手动配置这些常见内容,框架已做好决策。例如,默认的日志配置可让应用程序快速输出日志信息,无需开发者额外繁琐配置日志级别、输出格式与位置等。
-
约定的项目结构:Spring Boot 提倡特定项目结构,通常主应用程序类(含 main 方法)置于根包,控制器类、服务类、数据访问类等分别放在相应子包,如com.example.demo.controller 放控制器类,com.example.demo.service 放服务类等。此约定使团队成员更易理解项目结构与组织,新成员加入项目时能快速定位各功能代码位置,提升协作效率。
Spring Boot中如何实现对不同环境的属性配置文件的支持?
Spring Boot支持不同环境的属性配置文件切换,通过创建application-{profile}.properties文件,其中{profile}是具体的环境标识名称。
例如:application-dev.properties用于开发环境,application-test.properties用于测试环境。。如果要想使用application-dev.properties文件,则在application.properties文件中添加spring.profiles.active=dev。
Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
启动类上面的注解是@SpringBootApplication,它也是Spring Boot的核心注解,主要包含了以下3个注解:
-
@SpringBootConfiguration:继承自@Configuration,二者功能也一致,标注当前类是配置类。可以理解为一个Configuration就是对应的一个Spring的xml版的容器;一个被@Configuration标注的类,相当于一个ApplicationContext.xml文件。
-
@EnableAutoConfiguration:即把指定的类构造成对象,并放入Spring容器中,使其成为bean对象,作用类似@Bean注解。
-
@ComponentScan:主要作用是定义包扫描的规则,然后根据定义的规则找出哪些需类需要自动装配到Spring的bean容器中,然后交由Spring进行统一管理。标注了@Controller、@Service、@Repository、@Component 的类都可以别spring扫描到。
你如何理解Spring Boot中的Starter?
Starter可以理解为启动器,它的主要作用如下:
-
Starter可以维护对应的jar包的版本依赖,使得开发者不需要去关心版本冲突这种容易出错的细节,Starter组件会把对应功能的所有jar包依赖全部导入进来,避免了开发者自己去引入依赖带来的麻烦
-
Starter内部集成了自动装配的机制,也就是说在程序中依赖对应的starter组件以后,这个组件会自动集成到Spring生态下,并且对于相关Bean的管理,也是基于自动装配机制来完成
-
依赖Starter组件后,这个组件对应的功能所需要维护的外部化配置,会自动集成到SpringBoot中,只需要在Application.properties文件里面进行维护就行了,比如Redis这个Starter,只需要在Application.properties文件里面添加Redis的连接信息就可以直接使用了
Spring Boot Starter的工作原理是什么?
在SpringBoot启动的时候,按照约定去读取SpringBoot Starter的配置信息,再根据配置信息对资源进行初始化,并注入到Spring容器中。这样SpringBoot启动完毕后,就已经准备好了一切资源,使用过程中直接注入对应Bean资源即可。





