当前位置: 首页 > news >正文

Web后端进阶:springboot原理(面试多问)

1.配置优先级

3种配置文件:

  • application.properties
server.port=8081
  • application.yml
server:port: 8082
  • application.yaml
server:port: 8082

2种外部属性的配置(Java系统属性、命令行参数):

  • Java系统属性配置 (格式: -Dkey=value)
-Dserver.port=9000
  • 命令行参数 (格式:–key=value)
--server.port=10010

优先级(从低到高):

  • application.yaml(忽略)
  • application.yml
  • application.properties
  • java系统属性(-Dxxx=xxx)
  • 命令行参数(–xxx=xxx)

2.Bean的管理

2.1 Bean的作用域

在这里插入图片描述

  • 可以借助Spring中的@Scope注解来进行配置作用域

[图片]

注意事项:

  • IOC容器中的bean默认使用的作用域:singleton (单例)
  • 默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时)
  • prototype的bean,每一次使用该bean的时候都会创建一个新的实例
  • 实际开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性

2.2第三方Bean

之前我们所配置的bean,像controller、service,dao三层体系下编写的类,这些类都是我们在项目当中自己定义的类(自定义类)。当我们要声明这些bean,也非常简单,我们只需要在类上加上@Component以及它的这三个衍生注解(@Controller、@Service、@Repository),就可以来声明这个bean对象了。
但是在我们项目开发当中,还有一种情况就是这个类它不是我们自己编写的,而是我们引入的第三方依赖当中提供的,那么此时我们是无法使用 @Component 及其衍生注解来声明bean的,此时就需要使用@Bean注解来声明bean 了。

演示1:

  • 在启动类中直接声明这个Bean。比如:我们可以将我们之前使用的阿里云OSS操作的工具类,基于@Bean注解的方式来声明Bean。
import com.itheima.utils.AliyunOSSOperator;
import com.itheima.utils.AliyunOSSProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;@ServletComponentScan
@EnableScheduling
@SpringBootApplication
public class TliasWebManagementApplication {public static void main(String[] args) {SpringApplication.run(TliasWebManagementApplication.class, args);}@Beanpublic AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties ossProperties) {return new AliyunOSSOperator(ossProperties);}
}

演示2:
若要管理的第三方 bean 对象,建议对这些bean进行集中分类配置,可以通过 @Configuration 注解声明一个配置类。【推荐】

package com.itheima.config;import com.itheima.utils.AliyunOSSOperator;
import com.itheima.utils.AliyunOSSProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class OSSConfig {@Beanpublic AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties ossProperties) {return new AliyunOSSOperator(ossProperties);}
}
  • 通过@Bean注解的name 或 value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。
  • 如果第三方bean需要依赖其他bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。

3.SpringBoot原理

3.1起步依赖

在这里插入图片描述
当我们引入了 spring-boot-starter-web 之后,maven会通过依赖传递特性,将web开发所需的常见依赖都传递下来。
在这里插入图片描述

3.2自动配置

SpringBoot的自动配置就是当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。
在这里插入图片描述

3.2.1实现方案

3.2.1.1方案一

@ComponentScan组件扫描

@SpringBootApplication
@ComponentScan({"com.itheima","com.example"}) //指定要扫描的包
public class SpringbootWebConfigApplication {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfigApplication.class, args);}
}
3.2.1.2方案二

@Import导入

  • 导入形式主要有以下几种:
    1. 导入普通类
    2. 导入配置类
    3. 导入ImportSelector接口实现类

1). 使用@Import导入普通类:

@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
@SpringBootApplication
public class SpringbootWebConfigApplication {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfigApplication.class, args);}
}

2). 使用@Import导入配置类

  • 配置类
@Configuration
public class HeaderConfig {@Beanpublic HeaderParser headerParser(){return new HeaderParser();}@Beanpublic HeaderGenerator headerGenerator(){return new HeaderGenerator();}
}
  • 启动类
@Import(HeaderConfig.class) //导入配置类
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class, args);}
}

3). 使用@Import导入ImportSelector接口实现类:

  • ImportSelector接口实现类
public class MyImportSelector implements ImportSelector {public String[] selectImports(AnnotationMetadata importingClassMetadata) {//返回值字符串数组(数组中封装了全限定名称的类)return new String[]{"com.example.HeaderConfig"};}
}
  • 启动类
@Import(MyImportSelector.class) //导入ImportSelector接口实现类
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class, args);}
}

4). 使用第三方依赖提供的 @EnableXxxxx注解(best)

  • 第三方依赖中提供的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)//指定要导入哪些bean对象或配置类
public @interface EnableHeaderConfig { 
}
  • 在使用时只需在启动类上加上@EnableXxxxx注解即可
@EnableHeaderConfig  //使用第三方依赖提供的Enable开头的注解
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class, args);}
}

3.2.2原理分析

3.2.2.1源码跟踪

源码跟踪技巧:
在跟踪框架源码的时候,一定要抓住关键点,找到核心流程。一定不要从头到尾一行代码去看,一个方法的去研究,一定要找到关键流程,抓住关键点,先在宏观上对整个流程或者整个原理有一个认识,有精力再去研究其中的细节。

在这里插入图片描述
在@SpringBootApplication注解中包含了:

  • 元注解(不再解释)
  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

自动配置源码小结:
自动配置原理源码入口就是 @SpringBootApplication 注解,在这个注解中封装了3个注解,分别是:

  • @SpringBootConfiguration
    • 声明当前类是一个配置类
  • @ComponentScan
    • 进行组件扫描(SpringBoot中默认扫描的是启动类所在的当前包及其子包)
  • @EnableAutoConfiguration
    • 封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类)
      在实现类重写的selectImports()方法,读取当前项目下所有依赖jar包中META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports两个文件里面定义的配置类(配置类中定义了@Bean注解标识的方法)。

当SpringBoot程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息(类的全限定名)封装到String类型的数组中,最终通过@Import注解将这些配置类全部加载到Spring的IOC容器中,交给IOC容器管理。

3.2.2.2 @Conditional

@Conditional注解:

  • 作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring的IOC容器中。
  • 位置:方法、类
  • @Conditional本身是一个父注解,派生出大量的子注解:
    • @ConditionalOnClass:判断环境中有对应字节码文件,才注册bean到IOC容器。
    • @ConditionalOnMissingBean:判断环境中没有对应的bean(类型或名称),才注册bean到IOC容器。
    • @ConditionalOnProperty:判断配置文件中有对应属性和值,才注册bean到IOC容器。

最后再给大家梳理一下自动配置原理:
在这里插入图片描述

自动配置的核心就在@SpringBootApplication注解上,SpringBootApplication这个注解底层包含了3个注解,分别是:

  • @SpringBootConfiguration
  • @ComponentScan
  • @EnableAutoConfiguration

@EnableAutoConfiguration这个注解才是自动配置的核心。

  • 它封装了一个@Import注解,Import注解里面指定了一个ImportSelector接口的实现类。
  • 在这个实现类中,重写了ImportSelector接口中的selectImports()方法。
  • 而selectImports()方法中会去读取两份配置文件,并将配置文件中定义的配置类做为selectImports()方法的返回值返回,返回值代表的就是需要将哪些类交给Spring的IOC容器进行管理。
  • 那么所有自动配置类的中声明的bean都会加载到Spring的IOC容器中吗? 其实并不会,因为这些配置类中在声明bean时,通常都会添加@Conditional开头的注解,这个注解就是进行条件装配。而Spring会根据Conditional注解有选择性的进行bean的创建。
  • @Enable 开头的注解底层,它就封装了一个注解 import 注解,它里面指定了一个类,是 ImportSelector 接口的实现类。在实现类当中,我们需要去实现 ImportSelector 接口当中的一个方法 selectImports
    这个方法。这个方法的返回值代表的就是我需要将哪些类交给 spring 的 IOC容器进行管理。
  • 此时它会去读取两份配置文件,一份儿是 spring.factories,另外一份儿是 autoConfiguration.imports。而在 autoConfiguration.imports
    这份儿文件当中,它就会去配置大量的自动配置的类。
  • 而前面我们也提到过这些所有的自动配置类当中,所有的 bean都会加载到 spring 的 IOC 容器当中吗?其实并不会,因为这些配置类当中,在声明 bean 的时候,通常会加上这么一类@Conditional
    开头的注解。这个注解就是进行条件装配。所以SpringBoot非常的智能,它会根据 @Conditional
    注解来进行条件装配。只有条件成立,它才会声明这个bean,才会将这个 bean 交给 IOC 容器管理。

3.2.3自定义starter

3.2.3.1实现
  • 第1步:创建自定义starter模块 aliyun-oss-spring-boot-starter(进行依赖管理)
    • 把阿里云OSS所有的依赖统一管理起来
  • 第2步:创建autoconfigure模块 aliyun-oss-spring-boot-autoconfigure
    • 在starter中引入autoconfigure (我们使用时只需要引入starter起步依赖即可)
  • 第3步:在autoconfigure模块aliyun-oss-spring-boot-autoconfigure中完成自动配置
    1. 定义一个自动配置类,在自动配置类中将所要配置的bean都提前配置好
    2. 定义配置文件,把自动配置类的全类名定义在配置文件(META-INF/spring/xxxx.imports)中
http://www.dtcms.com/a/299784.html

相关文章:

  • Android Fragment 全解析
  • 【机器学习深度学习】微调能改变模型“智商”吗?——模型能力与知识的本质解析
  • (LeetCode 面试经典 150 题) 452. 用最少数量的箭引爆气球 (排序+贪心)
  • HCLP--MGER综合实验
  • ros2 中python 的多种调试方式
  • 《计算机组成原理与汇编语言程序设计》实验报告二 基本数字逻辑及汉字显示
  • 深入剖析 MetaGPT 中的提示词工程:WriteCode 动作的提示词设计
  • 深入React框架:构建现代前端应用的全面指南
  • 容器化成本优化:K8s资源请求与限制的黄金法则——从资源画像分析到25%成本削减的实战指南
  • 2025 年 Java 就业主流技术栈
  • Java学习第七十七部分——JVM运行时数据区
  • 三防平板搭载2D扫描头:工业数据采集的革新利器
  • 路由选择工具——IP-Prefix
  • springboot企业级后台管理平台-计算机毕业设计源码02282
  • java网络请求工具类HttpUtils
  • 如何查找php配置文件php.ini
  • URL与URI:互联网世界的“门牌号“与“身份证“
  • 【机器学习深度学习】模型微调:多久才算微调完成?——如何判断微调收敛,何时终止训练
  • Linux库——库的制作和原理(2)_库的原理
  • 微软中国高级架构师步绍鹏受邀为第十四届PMO大会演讲嘉宾
  • gig-gitignore工具实战开发(五):gig add完善
  • 单片机中的三极管
  • write`系统调用
  • 字节跳动正式开源AI智能体开发平台Coze
  • LeetCode——1957. 删除字符使字符串变好
  • 1.安装anaconda详细步骤(含安装截图)
  • Typecho插件开发实战:构建专业级访问日志系统
  • ESP32-idf学习(五)esp32C3移植lvgl①
  • 贝叶斯决策论
  • Spring AI MCP 客户端