springboot---四大核心

news2024/11/15 10:59:32

四大核心

  • Starter
    • 简介
    • 总结
  • Autoconfigure
    • 简介
    • 示例
    • 原理
    • 自定义starter
      • 打包
      • 实践
    • 总结
  • CLI
  • Actuator

Starter

简介

springboot项目中几乎项目依赖中基本上全是各种各样的starter, 那么到底什么是starter?

starter是一组方便的依赖描述符,当我们使用它时,可以获得所有需要的Spring和相关技术的一站式服务,典型的如spring-boot-starter-web,引入之后,自动引入所有有关spring web项目相关的依赖。

  • 官方提供的 starter 命名:spring-boot-starter-xxx

            <!--监控依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <!-- 如果开启了Actuator默认不开放的endpoints,建议一定要加上Spring Security用于endpoint保护,避免重要信息泄露,必须防止未经授权的外部访问。 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
  • 非官方的 starter 命名:xxx-spring-boot-starter

            <!-- druid连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
                <version>3.5.2</version>
            </dependency>
    
  • 其中的 xxx 就是我们想要依赖的组件或者 jar 包。引入之后通过简单的约定配置就可以正常使用。

  • Starter 帮我们封装好了所有需要的依赖,避免我们自己添加导致的一些Jar包冲突或者缺少包的情况。

总结

starter的存在让我们大大简化了项目的开发准备工作,开箱即用。有些starter 包的内容就是 pom 文件,就是一个依赖传递包;而有些Starter还帮我们自动注入了需要的 Bean 实例到 Spring 容器中,不需要我们手动配置。

Autoconfigure

简介

autoconfigure 在我们的开发中并不会被感知,因为它是存在与我们的 starter 中的。所以我们的每个 starter 都是依赖 autoconfigure 的

autoconfigure 内容是配置 Bean 实例到 Spring 容器的实际代码实现包,然后提供给 starter 依赖。所以说配置 Bean 实例到Spring容器中实际是 autoconfigure 做的,因为是 starter 依赖它,所以也可以说是 starter 干的。

所以:autocinfigure 是 starter 体现出来的能力的代码实现

示例

我相信,只要你用过Spring Boot,就会对这样一个现象非常的好奇:

引入一个组件依赖,加个配置,这个组件就生效了。

举个例子来说,比如我们常用的Redis, 在Spring Boot中的使用方式是这样的:

  1. 引入依赖

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 编写配置

    spring:
      redis:
        database: 0
        timeout: 5000ms
        host: 127.0.0.1
        port: 6379
        password: 123456
    
  3. 直接使用

    @Autowired
    private RedisTemplate redisTemplate;
    

这期间,我们做了什么嘛?我们什么也没有做,那么,这个RedisTemplate对象是怎么注入到Spring容器中的呢?

原理

记得刚开始学自动装配的时候,有两个注解用的很爽,分别是@Autowired和@Resource。当时还记得@Autowired默认装配是byType,可以通过@Qualifile为byName,@Resource默认装配是byName,找不到自动byType。然后还记得,加了@Component注解或其衍生注解之后就能装配了。那么,一个Bean是如何被加载到容器中的?

首先是看一个项目的启动类
在这里插入图片描述

分析这些注解,应该秘密就藏在@SpringBootApplication注解了
在这里插入图片描述
我们点进去源码可以发现,@SpringBootApplication是一个组合注解,其中上面那三个是属于Java提供的元注解,@Inherited是指可继承的(如果@SpringBootApplication注解作用于类A上,然后B继承了A,那么B也具有该注解的功能)。重要的注解是下面这三个@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan。

@SpringBootConfiguration
在这里插入图片描述看似很高大上的@SpringBootConfiguration注解,点进去一看,其实他就是继承了@Configuration,说白了,他就是一个配置注解,作用的话,就是表明某个类是一个配置类。

@ComponentScan

在这里插入图片描述这个注解默认会扫描该类所在的包下所有被@Component注解或其衍生注解所标注的类。

@EnableAutoConfiguration
在这里插入图片描述他是自动装配的总开关,意思是开启自动装配。

点进去可以看到有一个没见过的注解@AutoConfigurationPackage,这是什么作用呢?从名字中大致能看出,自动配置包,差不多吧,他的意思就是添加该注解的类所在的包作为 自动配置包进行管理,不太明白?点进去!
在这里插入图片描述

点进去,我们发现,里面有一个@Import({Registrar.class})
在这里插入图片描述

继续点进去,终于看到代码了,大致可以看出来,这是用来注册bean的,这里我们着重看一下registerBeanDefinitions方法,方法里有一个参数是BeanDefinitionRegistry registry,听名字就有那味了,重点来了,这里通过一个构造方法进行设置了packageNamenew PackageImports(metadata).getPackageNames(),接下来我要做什么,想必大家都知道了,点进去这个构造方法。
在这里插入图片描述

到这里终于把包名给set上了,接下来我们可以看看register方法了,温馨提示:刚刚是从register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));的构造方法点进来的(贵人多忘事嘛)。
在这里插入图片描述
这里会走else,这个方法呢,就完成了该包下的bean注入到容器中。

看完了@AutoConfigurationPackage注解,接下来看看这个@Import(AutoConfigurationImportSelector.class),这个是导入自动装配的ImportSelector类。 AutoConfigurationImportSelector
在这里插入图片描述

可以看到他实现了DeferredImportSelector接口
在这里插入图片描述

继续点,可以看到,他继承了ImportSelector接口。
在这里插入图片描述

在ImportSelector中有一个方法,是selectImports方法
在这里插入图片描述

可以清楚的看到,AutoConfigurationImportSelector实现了该方法
在这里插入图片描述

在这里首先是判断了自动装配的开关
在这里插入图片描述

然后获取需要装配的bean
在这里插入图片描述

其中这里的getCandidateConfigurations方法是读取META-INF/spring.factories
在这里插入图片描述

在AutoConfigurationImportSelector下,还有一个重要的静态内部类,该静态内部类的构造器中初始化读取META-INF/spring-autoconfigure-metadata.properties。
在这里插入图片描述

重点是两个配置类
在这里插入图片描述

点进去spring-autoconfigure-metadata.properties,里面是自动装配的一些元数据。
在这里插入图片描述

点进去spring.factories在这里插入图片描述

点进去一个可以发现,里面都是写好的bean,就等被加载呢!
在这里插入图片描述

只要我们按照约定来写spring.factories,那么我们也可以自己定义starter,把我们的bean封装到一个配置类中!

自定义starter

打包

首先需要深思一下什么是打包,现在项目都是分工合作,写好代码运维人员直接从git拉取项目部署,都快忘记了什么是打包。

打包的目的有两种:启动和引入,不同的目的打出来的包截然不同,并且是由maven自己判断的。

maven是怎么判断的:检测项目中是否存在启动类。

  • 没有启动类的项目打出来的包:
    在这里插入图片描述
    在这里插入图片描述
    打包时pom文件中的jar不会下载

  • 存在启动类时打出来的包
    在这里插入图片描述
    在这里插入图片描述
    打包时pom文件中的jar会下载

基于上面的示例可以发现spring项目有无启动类时打出来的包会有很大的差别。其实也好理解,存在启动类的项目,打包自然是为了运行;而没有启动类的包,打包自然是为了被引用。

实践

  1. 创建一个普通的springboot项目,可以命名为demo-spring-boot-starter
  2. 创建好之后,把启动类和test文件夹删掉,因为存在启动类和test文件夹打包出来的项目无法被依赖
  3. 创建需要自动装配的bean
  4. 将bean自动装配
  5. 将这个项目打包到我们本地的maven仓库
  6. 主项目像引入其他依赖一样引入该依赖就可以了
  7. 自定义starter中的bean就可以直接通过自动装配创建对象。

最终形成如下目录:
在这里插入图片描述

  • SpringTest
    package com.lkw.java.demo3.service;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @Description TODO()
     * @Authon lkw
     * @Date 2024/1/30 17:22
     * @Version 1.0
     **/
    
    @Configuration
    public class SpringTest {
    
        public String test(){
            System.out.println("demo3");
            return "demo3";
        }
    
        @Bean
        public SpringTest springTest(){
            return new SpringTest();
        }
    }
    
  • spring.factories
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lkw.java.demo3.service.SpringTest
    
  • pom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.1</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.lkw.java</groupId>
        <artifactId>demo3</artifactId>
        <version>0.0.1</version>
        <name>demo3</name>
        <description>starter project for Spring Boot</description>
        <properties>
            <java.version>8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!--表示两个项目之间依赖不传递;不设置optional或者optional是false,表示传递依赖-->
            <!--例如:project1依赖a.jar(optional=true),project2依赖project1,则project2不依赖a.jar-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-autoconfigure</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                    </plugin>
                </plugins>
            </pluginManagement>
    
        </build>
    
    </project>
    

总结

  • 自动装配的实现原理核心是SPI机制。SPI ,全称为 Service Provider Interface(服务提供者接口),是一种服务发现机制。它通过在classpath路径下的META-INF/services文件夹查找文件,自动加载文件中所定义的类。

  • 并不是每个spring-boot-starter-x中都有注入文件。所有spring-boot-starter-x的组件配置都是放在spring-boot-autoconfigura的组件中的

  • 自动装配简述:项目启动时,Spring通过@Import注解导入了AutoConfigurationImportSelector, 然后调用该类selectImports时,从classpath下的META-INF/spring.factories文件中读取key为EnableAutoConfiguration的配置类,然后Spring便会将这些类加载到Spring的容器中,变成一个个的Bean。

CLI

Spring Boot CLI 是一个命令行使用 Spring Boot 的客户端工具;主要功能如下:

  • 运行 groovy 脚本
  • 打包 groovy 文件到 jar
  • 初始化 Spring Boot 项目
  • 其他详见官网:https://docs.spring.io/spring-boot/docs/current/reference/html/cli.html

Actuator

actuator 是 Spring Boot 的监控插件,本身提供了很多接口可以获取当前项目的各项运行状态指标。

  1. 添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
  2. 配置需要开启监控的端点

    management:
      endpoint:
        health: ## 开启健康监控端点
          enabled: true
        beans: ## 开启Bean实例监控端点
          enabled: true
    

    重要端点:

    • health端点:端点会聚合你程序的健康指标,来检查程序的健康情况,端点有很多自动配置的健康指示器:如 redis、rabbitmq、db 等组件。

    • metrics端点:用来返回当前应用的各类重要度量指标,比如:内存信息、线程信息、垃圾回收信息、tomcat、数据库连接池等。

    • loggers端点:暴露了我们程序内部配置的所有 logger 的信息,能够动态修改你的日志等级;只需要发起一个 URL 为http://localhost:8080/actuator/loggers/root的POST请求,POST 报文如下:

      {  
         "configuredLevel": "DEBUG"  
      }
      
    • info端点:可以用来展示你程序的信息。我理解过来就是一些程序的基础信息。并且你可以按照自己的需求在配置文件application.properties中个性化配置(默认情况下,该端点只会返回一个空的 json 内容。)

    • beans端点:会返回 Spring 容器中所有 bean 的别名、类型、是否单例、依赖等信息

    • heapdump端点:会自动生成一个 Jvm 的堆文件 heapdump。我们可以使用 JDK 自带的 Jvm 监控工具 VisualVM 打开此文件查看内存快照。

    • threaddump端点:主要展示了线程名、线程 ID、线程的状态、是否等待锁资源、线程堆栈等信息。方便我们在日常定位问题的时候查看线程的情况。

    • shutdown端点:属于操作控制类端点,可以优雅关闭 Spring Boot 应用。要使用这个功能首先需要在配置文件中开启:management.endpoint.shutdown.enabled=true

  3. 启动服务并验证

  4. 查看各个监控信息

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推荐系统|排序_多目标模型

文章目录 四大特征用户特征物品特征统计特征场景特征 训练过程中会遇到的问题 四大特征 ID相当于是人拥有的身份证&#xff0c;能够唯一确定出一个人 用户特征 主要指的是用户ID和用户画像 物品特征 主要是指物品ID和物品画像以及物品持有人。 统计特征 统计特征既包括对…

Java并发基础:CompletionService全面解析!

内容概要 CompletionService的优点在于能够解耦任务提交与结果获取&#xff0c;有效的整合线程池与阻塞队列&#xff0c;实现任务完成顺序的处理&#xff0c;提升系统吞吐量&#xff0c;它简化了多线程编程的复杂性&#xff0c;使开发者能够更专注于业务逻辑&#xff0c;而不必…

【昕宝爸爸小模块】深入浅出详解之常见的语法糖

深入浅出详解之常见的语法糖 一、&#x1f7e2;关于语法糖的典型解析二、&#x1f7e2;如何解语法糖&#xff1f;2.1&#x1f7e2;糖块一、switch 支持 String 与枚举2.2&#x1f4d9;糖块二、泛型2.3&#x1f4dd;糖块三、自动装箱与拆箱2.4&#x1f341;糖块四、方法变长参数…

TOP100 矩阵

1.73. 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 提示&#xff1a; m matrix.lengthn matrix[0].length1 < m, n < 200-2^31 < matrix[i][j] < 2^31 - 1 思路&#xf…

宏景eHR FrCodeAddTreeServlet SQL注入漏洞复现

前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 一、产…

【排序算法】C语言实现随机快排,巨详细讲解

文章目录 &#x1f680;前言&#x1f680;快排的核心过程partition&#xff08;划分过程&#xff09;&#x1f680;快排1.0&#x1f680;随机快速排序&#x1f680;稳定性 &#x1f680;前言 铁子们好啊&#xff01;继续我们排序算法今天要讲的是快排&#xff0c;通常大家所说…

❤搭建一个Springboot项目(ltbjava)

❤从0实现一个项目 搭建好我们的java环境和运行的IDEA软件以后&#xff0c;接下来我们就应该实现一个自己的项目了 0 项目描述 基于jdk17 的学习&#xff0c;因为据说最新的spring框架的最低要求是jdk17Maven 3.8.7PS&#xff1a;springboot3.0版本以上必须用jdk171、 项目创…

STM32F407移植OpenHarmony笔记6

继上一篇笔记&#xff0c;编译好STM32的裸机程序&#xff0c;能点亮LED灯了。 下一步就是启动liteos_m内核了。 不过为了更好的调试代码&#xff0c;需要先把printf重定向到串口&#xff0c;基于gcc的printf重定向和Keil不一样。 直接新建printf.c&#xff0c;在里面重写printf…

摄像头监控系统/视频监控云平台EasyCVR接入单兵设备后如何配置移动规矩

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体控可实现视频监控直播、视频轮播、视频录像…

C#学习笔记_类(Class)

类的定义 类的定义是以关键字 class 开始&#xff0c;后跟类的名称。类的主体&#xff0c;包含在一对花括号内。 语法格式如下&#xff1a; 访问标识符 class 类名 {//变量定义访问标识符 数据类型 变量名;访问标识符 数据类型 变量名;访问标识符 数据类型 变量名;......//方…

氢气泄漏检测仪使用方法:守护安全,从细节开始

随着科技的发展&#xff0c;我们的生活和工作环境中充满了各种潜在的危险。其中&#xff0c;氢气作为一种清洁能源&#xff0c;其使用日益广泛&#xff0c;但同时也带来了泄漏的风险。为了确保我们的安全&#xff0c;了解并正确使用氢气泄漏检测仪至关重要。下面将详细介绍氢气…

yum一直出现正在尝试其它镜像... 解决方法

更改yum镜像源地址为阿里云镜像即可 1. 去ail云yum镜像源官网 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 (aliyun.com) 2. 选择自己对应的操作系统这里以centos7演示&#xff1a; 3. 先备份原yum配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/Ce…

OC源码 - FailureDetectionPeriodBlockMinutes参数解读

FailureDetectionPeriodBlockMinutes 看看官方文档中对该参数如何描述 orchestrator will detect failures to your topology, always. As a matter of configuration you may set the polling frequency and specific ways for orchestrator to notify you on such detectio…

Selenium处理Alert弹窗

页面弹窗有 3 种类型&#xff1a; alert&#xff08;警告信息&#xff09; confirm&#xff08;确认信息&#xff09; prompt&#xff08;提示输入&#xff09; 对于页面出现的 alert 弹窗&#xff0c;Selenium 提供如下方法&#xff1a; 序号 方法/属性 描述 1 ac…

【Delphi】IDE 工具栏错乱恢复

由于经常会在4K和2K显示器上切换Delphi开发环境(IDE)&#xff0c;导致IDE工具栏错乱&#xff0c;咋样设置都无法恢复&#xff0c;后来看到红鱼儿的博客&#xff0c;说是通过操作注册表的方法&#xff0c;能解决&#xff0c;试了一下&#xff0c;果真好用&#xff0c;非常感谢分…

Linux split命令 切割文件

目录 一. 主要配置项二. 按照行数切割文件三. 按照指定大小切割文件 一. 主要配置项 ⏹将文件按照行数或者大小切割为若干份小文件&#xff0c;主要作用就是用来切割文件 -l&#xff1a;表示将文件按照行分割-d&#xff1a;表示使用数字作为分割后的文件名后缀, 而不是默认的…

java生成dll,并利用c语言使用libcurl调用http接口

本文可能需要使用的环境和工具&#xff1a; c/ c和GCC编译器 (Windows) Cygwin或MinGW 本文运行环境为windows10&#xff0c;使用MinGW-W64-builds-4.2.0 curl-8.5.0 libcurl 可以在官网 http://curl.haxx.se/ 获得。 配置MinGW 将mingw.rar解压到D:&#xff0c;修改系统…

软件压力测试:探究其目的与重要性

随着软件应用在各行各业中的广泛应用&#xff0c;确保软件在高负载和极端条件下的稳定性变得至关重要。软件压力测试是一种验证系统在不同负载条件下的性能和稳定性的方法。本文将介绍软件压力测试的目的以及为什么它对软件开发和部署过程至关重要。 验证系统性能的极限&#x…

C#: 软件任务栏托盘图标添加关闭软件菜单等

说明&#xff1a;在软件在任务栏右下角的系统托盘的图标添加个右键弹出菜单功能&#xff0c;案例实现右键弹窗菜单关闭软件功能。 1.添加系统托盘图标控件 NotifyIcon 2.右键打开控件属性菜单添加鼠标点击事件函数 3.事件函数添加代码 //右键点击任务栏图标弹出关闭菜单 priv…

python爬虫之豆瓣首页图片爬取

网址&#xff1a;https://movie.douban.com/ import requests from lxml import etree import re url https://movie.douban.com headers {User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari/5…