7--SpringBoot-后端开发、原理详解(面试高频提问点)

目录

SpringBoot原理

起步依赖

自动配置

配置优先级

Bean设置

获取Bean

第三方Bean 


SpringBoot原理

内容偏向于底层的原理分析

基于Spring框架进行项目的开发有两个不足的地方:

  1. pom.xml中依赖配置比较繁琐,在项目开发时,需要自己去找到对应的依赖,还需要找到依赖它所配套的依赖以及对应版本,否则就会出现版本冲突问题。
  2. 在使用Spring框架进行项目开发时,需要在Spring的配置文件中做大量的配置,这就造成Spring框架入门难度较大,学习成本较高。
SpringBoot 框架底层提供了两个非常重要的功能:一个是起步依赖,一个是自动配置
  1. 通过SpringBoot所提供的起步依赖,就可以大大的简化pom文件当中依赖的配置,从而解决了Spring框架当中依赖配置繁琐的问题。
  1. 通过自动配置的功能就可以大大的简化框架在使用时bean的声明以及bean的配置。我们只需要引入程序开发时所需要的起步依赖,项目开发时所用到常见的配置都已经有了,我们直接使用就可以了。

起步依赖

起步依赖的原理就是Maven的依赖传递。

如果使用了SpringBoot,就不需要繁琐的引入依赖了。只需要引入一个依赖就可以了,那就是web开发的起步依赖:springboot-starter-web

问题:为什么只需要引入一个web开发的起步依赖,web开发所需要的所有的依赖都有了呢?

答案:因为Maven的依赖传递

在SpringBoot提供的这些起步依赖当中,已提供了当前程序开发所需要的所有的常见依赖(官网地址:https://docs.spring.io/spring-boot/docs/2.7.7/reference/htmlsingle/#using.build-systems.starters)。

比如:springboot-starter-web,这是web开发的起步依赖,在web开发的起步依赖当中,就 集成了web开发中常见的依赖:json、web、webmvc、tomcat等。只需要引入这一个起步依赖,其他的依赖都会自动的通过Maven的依赖传递进来。

自动配置

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

比如:我们要进行事务管理、要进行AOP程序的开发,此时就不需要我们再去手动的声明这些bean对象了,我们直接使用就可以从而大大的简化程序的开发,省去了繁琐的配置操作。

在CommonConfig配置类上添加了一个注解@Configuration,而@Configuration底层就是@Component,所以配置类CommonConfig最终也是SpringIOC容器当中的一个bean对象

  • 问题:在当前项目中我们并没有声明谷歌提供的Gson这么一个bean对象,然后我们却可以通过@AutowiredSpring容器中注入bean对象,那么这个bean对象怎么来的?
  • 答案SpringBoot项目在启动时通过自动配置完成了bean对象的创建。
  • 问题:当前包:com.itheima, 第三方依赖中提供的包:com.example,此时引入进来的第三方依赖当中的bean以及配置类为什么没有生效?

  • 答案:在类上添加@Component注解来声明bean对象时,还需要保证@Component注解能被Spring的组件扫描到。

  • SpringBoot项目中的@SpringBootApplication注解,具有包扫描的作用,但是它只会扫描启动类所在的当前包以及子包。

  • 当前包:com.itheima, 第三方依赖中提供的包:com.example(扫描不到)

  • 解决:
  • 方案1@ComponentScan 组件扫描,指定要扫描的包
  • 方案2@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中)
方案一:
@SpringBootApplication
@ComponentScan({"com.itheima","com.example"}) //指定要扫描的包
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}

进行项目开发时,当需要引入大量的第三方的依赖,就需要在启动类上配置N多要扫描的包,这种方式会很繁琐。而且这种大面积的扫描性能也比较低。

缺点:

1. 使用繁琐

2. 性能低

不推荐使用
方案二
@Import 导入

导入形式主要有以下几种:

1. 导入普通类

2. 导入配置类

3. 导入ImportSelector接口实现类

1.导入普通类 

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

2.导入配置类

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

3.接口实现类

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);
}
}

问题:如果基于以上方式完成自动配置,当要引入一个第三方依赖时,是不是还要知道第三方依赖中有哪些配置类和哪些Bean对象?

答案:是的。 (对程序员来讲,很不友好,而且比较繁琐)

问题:当我们要使用第三方依赖,依赖中到底有哪些bean和配置类,谁最清楚?

答案:第三方依赖自身最清楚。

结论:我们不用自己指定要导入哪些bean对象和配置类了,让第三方依赖它自己来指定。 

问题:怎么让第三方依赖自己指定bean对象和配置类?

答案:比较常见的方案就是第三方依赖提供一个注解,这个注解一般都以@EnableXxxx开头的注解,注解中封装的就是@Import注解

4.使用第三方依赖提供的 @EnableXxxxx注解(SpringBoot当中所采用的方式)

第三方依赖中提供的注解

@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);
}
}

配置优先级

SpringBoot 项目当中支持的三类配置文件:
  • application.properties
  • application.yml
  • application.yaml

配置文件优先级排名(从高到低):

1. properties配置文件

2. yml配置文件

3. yaml配置文件

SpringBoot项目当中除了以上3种配置文件外,SpringBoot为了增强程序的扩展性,除了支持配置文件的配置方式以外,还支持另外两种常见的配置方式:

1. Java系统属性配置 (格式: -Dkey=value

-Dserver.port=9000

2. 命令行参数 (格式:--key=value

--server.port=10010

优先级: 命令行参数 > 系统属性参数 > properties参数 > yml参数 > yaml参数

项目打包

点击右侧Maven中的package进行打包

显示打包完成

找到jar包的文件目录:

在当前目录下输入cmd回车,即可在当前目录下打开命令行

通过指令

  • java -Dserver.port=9000 -jar tlias-0.0.1-SNAPSHOT.jar 
  • java -jar tlias-0.0.1-SNAPSHOT.jar --server.port=9000
  • java -Dserver.port=9000 -jar tlias-0.0.1-SNAPSHOT.jar --server.port=10010

以上三种方式可更改端口号,第三种端口号改为10010,因为命令行参数优先级高于java系统属性

通过ctrl c可结束操作

优先级顺序,从高到低:

  • 命令行参数(--xxx=xxx

  • java系统属性(-Dxxx=xxx

  • application.properties

  • application.yml

  • application.yaml(忽略)

Bean设置

通过Spring当中提供的注解@Component以及它的三个衍生注解(@Controller@Service@Repository)来声明IOC容器中的bean对象,为应用程序注入运行时所需要依赖的bean对象,也就是依赖注入DI

获取Bean

默认情况下,SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过 程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对 象,就直接进行依赖注入就可以了。

Spring容器中提供了一些方法,可以主动从IOC容器中获取到bean对象,下面介绍3种常用方式:

1. 根据name获取bean

Object getBean(String name)

2. 根据类型获取bean

<T> T getBean(Class<T> requiredType)

3. 根据name获取bean(带类型转换)

<T> T getBean(String name, Class<T> requiredType)

@SpringBootTest
class SpringbootWebConfig2ApplicationTests {
@Autowired
private ApplicationContext applicationContext; //IOC容器对象
//获取bean对象
@Test
public void testGetBean(){
//根据bean的名称获取
DeptController bean1 = (DeptController)
applicationContext.getBean("deptController");
System.out.println(bean1);
//根据bean的类型获取
DeptController bean2 = applicationContext.getBean(DeptController.class);
System.out.println(bean2);
//根据bean的名称 及 类型获取
DeptController bean3 = applicationContext.getBean("deptController",
DeptController.class);
System.out.println(bean3);
}
}

默认bean对象是单例模式(只有一个实例对象)。那么如何设置bean对象为非单例呢?需要设置bean的作用域。

作用域说明
singleton
容器内同名称的 bean 只有一个实例(单例)(默认)
prototype
每次使用该 bean 时会创建新的实例(非单例)
request
每个请求范围内会创建新的实例( web 环境中,了解)
session
每个会话范围内会创建新的实例( web 环境中,了解)
application
每个应用范围内会创建新的实例( web 环境中,了解)

借助Spring中的@Scope注解来配置Bean的作用域

测试一

默认bean的作用域为:singleton (单例)

@Lazy //延迟加载(第一次使用bean对象时,才会创建bean对象并交给ioc容器管理)
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
public DeptController(){
System.out.println("DeptController constructor ....");
}
//省略其他代码...
}

测试二

@Scope("prototype") //bean作用域为非单例
@Lazy //延迟加载
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
public DeptController(){
System.out.println("DeptController constructor ....");
}
//省略其他代码...
}

第三方Bean 

要从IOC容器当中来获取到bean对象,需要先拿到IOC容器对象,怎么样才能拿到IOC容器呢?

想获取到IOC容器,直接将IOC容器对象注入进来就可以了

在配置类中定义@Bean标识的方法

如果需要定义第三方Bean时, 通常会单独定义一个配置类

@Configuration //配置类 (在配置类当中对第三方bean进行集中的配置管理)
public class CommonConfig {
//声明第三方bean
@Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
//通过@Bean注解的name/value属性指定bean名称, 如果未指定, 默认是方法名
public SAXReader reader(DeptService deptService){
System.out.println(deptService);
return new SAXReader();
}
}

如果是在项目当中我们自己定义的类,想将这些类交给IOC容器管理,我们直接使用@Component 以及它的衍生注解来声明就可以。

如果这个类它不是我们自己定义的,而是引入的第三方依赖当中提供的类,而且我们还想将这个类 交给IOC容器管理。此时我们就需要在配置类中定义一个方法,在方法上加上一个@Bean注解,通过这种方式来声明第三方的bean对象。

注解:8--SpringBoot原理分析、注解-详解(面试高频提问点)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/881082.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

最新编程语言排行榜:Python创新高!

2024年编程语言排行榜又迎来了令人惊喜的变化&#xff01;Python&#xff0c;这门因简单易学而受到广大程序员青睐的语言&#xff0c;再次突破历史记录&#xff0c;稳居排行榜前列。无论是数据分析、机器学习&#xff0c;还是Web开发&#xff0c;Python都展现出了强大的生命力和…

828华为云征文 | 使用Flexus云服务器X实例部署GLPI资产管理系统

828华为云征文 | 使用Flexus云服务器X实例部署GLPI资产管理系统 1. 部署环境说明2. 部署基础环境2.1. 操作系统基本配置2.2. 部署Nginx2.3. 部署MySQL2.4. 部署PHP 3. 部署GLPI资产管理系统 1. 部署环境说明 本次环境选择使用华为云Flexus云服务器X实例&#xff0c;因为其具有高…

无人机之AI跟踪篇

无人机的AI识别技术依托于计算机视觉和深度学习技术&#xff0c;实现了对目标的快速精准识别&#xff0c;在多个领域展现出了巨大的应用潜力和价值。以下是对无人机AI识别技术的详细解析&#xff1a; 一、无人机AI识别算法的基础原理 无人机AI识别算法主要基于先进的计算机视觉…

【刷题日记】15. 三数之和

15. 三数之和 两数之和可以用巧思也可以用map 三数之和会更加复杂一点&#xff0c;且这道题还需要考虑避免重复答案&#xff01; 思路&#xff1a; 特判&#xff1a;检如果nums 为 null 或长度小于 3直接返回空数组。排序&#xff1a;使用 sort对数组进行升序排序。就变成了…

JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)

大家好&#xff0c;今天我要分享的是如何在树形结构的数据中&#xff0c;根据特定条件设置节点及其所有子节点的显示属性。在实际项目中&#xff0c;这种需求非常常见&#xff0c;特别是在需要动态展示和隐藏节点的情况下。下面我将通过一个具体的示例来讲解实现过程。 需求分析…

Web开发:ABP框架3——入门级别的接口增删改查实现原理

一、上节回顾 运用了ABP框架&#xff0c;使用了EFcore进行增删改查 二、程序的入口 代码解说&#xff1a; public class Program // 定义程序主类 {public async static Task<int> Main(string[] args) // 主方法&#xff0c;返回状态码{// 配置Serilog日志Log.Logger…

【QT】定时器使用

文章目录 关于 Qt 定时器使用的注意细节总结实例-检查工具使用周期时间是否合理UI设计头文件 remind.h源文件 remind.cpp实现效果 关于 Qt 定时器使用的注意细节总结 一、创建与初始化 使用 QTimer 类来创建定时器。可以在构造函数中指定父对象&#xff0c;确保定时器在正确的…

【C++】STL----list常见用法

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;C从小白到高手 &#x1f339;往期回顾&#x1f339;&#xff1a;[C]vector常见用法 &#x1f516; 流水不争&#xff0c;争的是滔滔不息。 文章目录 一、list的介绍li…

【网络通信基础与实践第二讲】包括互联网概述、互联网发展的三个阶段、互联网的组成、计算机网络的体系结构

一、互联网概述 计算机网络是由若干节点&#xff08;node&#xff09;和连接这些节点的链路&#xff08;link&#xff09;组成。 网络之间还可以通过路由器互联起来&#xff0c;这就构成了一个覆盖范围更大的计算机网络。这样的网络称为互联网。 网络把许多计算机连接在一起…

SpringCloud-04 OpenFeign服务调用与负载均衡

OpenFeign是一个声明式、模板化的HTTP客户端&#xff0c;它简化了在Java应用程序中调用RESTful API的过程。OpenFeign是Netflix开发的一个开源项目&#xff0c;它构建在Feign的基础上&#xff0c;为开发者提供了更加简单、灵活的方式来实现HTTP请求。OpenFeign的特点包括&#…

计算机网络:概述 - 性能指标

目录 一. 速率 二. 带宽 三. 吞吐量 四. 时延 五. 时延带宽积 六. 往返时间RTT 七. 利用率 八. 丢包率 此博客介绍计算机网络中的性能指标&#xff0c;性能指标从不同的角度来度量计算机网络的性能。下面介绍几个常用的性能指标&#xff1a; 一. 速率…

服务器非法关闭后MySQL服务启动失败

在写这篇文章前&#xff0c;我弄好了&#xff0c;写完之后把成功安装的几个MySQL都删除了&#xff0c;只留了最后测试成功的服务“mysql-test” ,然后点击运行&#xff0c;发现又出现上图的错误。心态炸了。 本以为定位到问题了&#xff0c;但是这个错误让我迷茫了。我只能临时…

基于spring的ssm整合

目录 基于spring的ssm整合 Spring 框架 SpringMVC 框架 MyBatis 框架 1.创建项目 2.导入依赖 3.导入sql 4.创建jdbc.propries文件 1&#xff09;mysql8以下 2&#xff09;mysql8以上的 5.创建mybatis-config.xml配置文件 6.创建spring-Config.xml文件 7.创建项目所需包和类 1&a…

.whl文件下载及pip安装

以安装torch_sparse库为例 一、找到自己需要的版本&#xff0c;点击下载。 去GitHub的pyg-team主页中找到pytorch-geometric包。网址如下&#xff1a; pyg-team/pytorch_geometric​github.com/pyg-team/pytorch_geometric 然后点击如图中Additional Libraries位置的here&am…

Android系统dumpsys命令详解

文章目录 1. dumpsys 的工作原理2. 基本使用方法执行 dumpsys限制 dumpsys 的输出 3. 常见的 dumpsys 服务1. Activity Manager (activity)2. Battery Service (battery)3. Window Manager (window)4. Package Manager (package)5. Power Manager (power)6. Media DRM (media.d…

青柠视频云——视频丢包(卡顿、花屏、绿屏)排查

一、问题说明 近期有客户反馈&#xff0c;接入平台的设备经常出来卡顿、花屏、录屏的情况&#xff0c;出现这样的场景很是尴尬。 客户是私有化部署在公网环境&#xff0c;于是我们联系客户&#xff0c;对问题进行追踪排查。 二、场景复现 我们现场情况确认的过程中&#xff0c;…

Web 安全基础教程:从零基础入门到精通

一、Web 安全概述 &#xff08;一&#xff09;Web 安全的定义与重要性 1.定义 Web 安全是指保护 Web 应用程序免受各种网络威胁&#xff0c;确保 Web 服务的保密性、完整性和可用性。在当今数字化时代&#xff0c;Web 应用广泛存在于各个领域&#xff0c;从电子商务到社交媒…

Vue 实现高级穿梭框 Transfer 封装

文章目录 01 基础信息1.1. 技术栈1.2. 组件设计a. 竖版设计稿b. 横版设计稿 02 技术方案&#xff08;1&#xff09;初定义数据&#xff08;2&#xff09;注意事项&#xff08;3&#xff09;逻辑草图 03 代码示例3.1. 组件使用3.2. 组件源码./TransferPlus/index.vue./TransferP…

《史上最简单的 SpringCloud 教程》

Finchley版本 Spring Cloud Finchley; Spring Boot 2.0.3 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现&#xff08;Eureka&#xff09;(Finchley版本)史上最简单的SpringCloud教程 | 第二篇: 服务消费者&#xff08;restribbon&#xff09;(Finchley版本)史上最…

有没有自带财务管理功能的海外仓系统?

在全球化的商业环境中&#xff0c;海外仓作为连接国际市场的物流枢纽&#xff0c;其重要性日益凸显。然而&#xff0c;随着业务范围的扩展和费用类型的多样化&#xff0c;海外仓在财务管理上面临着诸多挑战。传统的手工计费和对账方式不仅耗时费力&#xff0c;而且容易出错&…