Spring Boot 学习之路 -- 基础认知

前言

  1. 最近因为业务需要,被拉去研究后端的项目,代码框架基于 Spring Boot,对我来说完全小白,需要重新学习研究…
  2. 出于个人习惯,会以 Blog 文章的方式做一些记录,文章内容基本来源于「 Spring Boot 从入门到精通(明日科技) 」一书,做了一些整理,更易于个人理解和回顾查找,所以大家如果希望更系统性的学习,可以阅读此书(比较适合我这种新手)。

一、概述

Spring Boot 是在 Spring 的基础上发展而来的全新的开源框架。它是由 Pivotal 团队开发的。开发 Spring Boot 的主要动机是简化部署 Spring 应用程序的配置过程。也就是说,使用 Spring Boot 能够以更简单的、更灵活的方式开发 Spring 应用程序。

Spring Boot的主要特点如下:

▪️ Spring Boot 的代码非常少。Spring 的注解驱动编程避免了大量的配置工作,并且 Spring Boot 可以自动创建各种工厂类,程序开发人员直接通过依赖注入就可以获取各类对象。

▪️ Spring Boot 的配置非常简单。程序开发人员只需在 application.properties 或 application.yml 文件中编写一些配置项就可以影响整个项目。即使不编写任何配置,项目也可以采用一套默认配置正常启动。Spring Boot 支持使用 @Configuration 注解管理、维护配置类,让配置工作变得更灵活。

▪️ Spring Boot 可以自动部署。Spring Boot 自带 Tomcat 服务器,在项目启动的过程中可以自动完成所有资源的部署操作。

▪️ Spring Boot 易于单元测试。Spring Boot 自带 JUnit 单元测试框架,可以直接测试各个组件中的方法。

▪️ Spring Boot 集成了各种流行的第三方框架或软件。Spring Boot 提供了许多集成其他技术的依赖包,程序开发人员可以直接通过这些依赖包调用第三方框架或软件,例如 Redis、MyBatis、ActiveMQ 等。

▪️ Spring Boot 项目启动的速度很快。即使项目有庞大的依赖库,仍能在几秒之内完成部署和启动。


二、基础

因为注解在 Spring Boot 中发挥着至关重要的作用,所以为了能够快速地掌握 Spring Boot,须明确什么是注解和 Spring Boot 常用注解的功能及其标注位置。在 Spring Boot 容器中,存放着很多的 Bean。为此,须明确 Bean 是什么,并深入理解与其相关的两个过程:注入 Bean 和注册 Bean。在开发 Spring Boot 项目中,离不开“依赖”,我们须掌握如何为项目添加依赖。与此同时,还须掌握如何为 Spring Boot 项目中的程序元素命名。

2.1 注解

在程序开发的过程中,注解是无处不在的。但是,注解又不是必需的;换言之,在不使用注解的情况下,也能够开发程序。只不过,掌握注解能够帮助程序开发人员深入理解框架,进而提高程序开发的效率。那么,什么是注解呢?注解的作用又有哪些呢?

2.1.1 概念及其应用

在给出注解的概念之前,须明确什么是元数据。所谓元数据,指的是用于描述数据的数据。下面结合某个配置文件里的一行信息,举例说明什么是元数据。

<string name="app_name">AnnotionProject</string>​​

上述信息中的数据 “app_name” 是用于描述数据 AnnotionProject 的。也就是说,数据 “app_name” 就是元数据。那么,什么是注解呢?注解又被称作标注,是一种被加入源码的具有特殊语法的元数据。

需要特别说明的是:

  • 注解仅仅是元数据,和业务逻辑无关。
  • 虽然注解不是程序本身,但是可以对程序做出解释。
  • 应用程序中的类、方法、变量、参数、包等程序元素都可以被注解。

理解了“什么是注解”后,再来了解一下在应用程序中注解的应用体现在哪些方面:

  • 在编译时进行格式检查。例如,如果被 @Override 标记的方法不是父类的某个方法,编译器就会报错。
  • 减少配置。依据代码的依赖性,使用注解替代配置文件。
  • 减少重复工作。在程序开发的过程中,通过注解减少对某个方法的调用次数。

2.1.2 常用注解及其标注位置

Spring Boot 是一个支持海量注解的框架:

注解标注位置功能
@autowired成员变量自动注入依赖
@Bean方法@Bean 用于注册 Bean,当 @Bean 标记方法时,等价于在 XML 中配置 Bean
@Component用于注册组件。当不清楚注册类属于哪个模块时就用这个注释
@ComponentScan开启组件扫描器
@Configuration声明配置类
@ConfigurationProperties用于加载额外的 properties 配置文件
@Controller声明控制器类
@ControllerAdvice可用于声明全局异常处理类和全局数据处理类
@EnableAutoConfiguration开启项目的自动配置功能
@ExceptionHandler方法用于声明处理全局异常的方法
@Import用于导入一个或者多个 @Configuration 注解标注的类
@ImportResource用于加载 XML 配置文件
@PathVariable方法参数让方法参数从 URL 中的占位符中取值
@Qualifier成员变量与 @Autowired 配合使用,当 Spring 容器中有多个类型相同的 Bean 时,可以用 @Qualifier(“name”) 来指定注入哪个名称的 Bean
@RequestMapping方法指定方法可以处理哪些 URL 请求
@RequestParam方法参数让方法参数从 URL 参数中取值
@Resource成员变量与 @Autowired 功能类似,但是有 name 和 type 两个参数,可根据 Spring 配置的 Bean 的名称进行注入
@ResponseBody方法表示方法的返回结果直接写入 HTTP response body 中。如果返回值是字符串,则直接在网页上显示该字符串
@RestController相当于 @Controller 和 @ResponseBody 的合集,表示在这个控制器下的所有方法都被 @ResponseBody 标注
@Service服务的实现类用于声明服务的实现类
@SpringBootApplication主类用于声明项目主类
@Value成员变量动态注入,支持 " #{ } " 与 " ${ } " 表达式

这些注解的编码位置是非常灵活的。当注解用于标注类、成员变量和方法时,注解的编码位置既可以在成员变量的上边,例如:

@Autowired
​​​​private String name;

又可以在成员变量的左边,例如:

@Autowired private String name;​​

在 Spring Boot 的常用注解中,需特别说明的是,使用 @RequestParam 能够标注方法中的参数。例如:

​​​​@RequestMapping("/user")
​​​​@ResponseBody
​​​​public String getUser(@RequestParam Integer id) {
​​​​    return "success";
​​​​}

2.1.3 使用@SpringBootApplication标注启动类

使用注解能够启动一个 Spring Boot 项目,这是因为在每一个 Spring Boot 项目中都有一个启动类(主类),并且启动类必须被 @SpringBootApplication 注解标注,进而能够调用用于启动一个 Spring Boot 项目的 SpringApplication.run() 方法。

如下:

package com.spark.springbootlearning;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootLearningApplication {public static void main(String[] args) {SpringApplication.run(SpringBootLearningApplication.class, args);}}

@SpringBootApplication 注解虽然重要,但使用起来非常简单,因为这个注解是由多个功能强大的注解整合而成的。

打开 @SpringBootApplication 注解的源码可以看到它被很多其他注解标注,其中最核心的 3 个注解分别是:

  • SpringBootConfiguration 注解:让项目采用基于 Java 注解的配置方式,而不是传统的 XML 文件配置。当然,如果程序开发人员写了传统的 XML 配置文件,Spring Boot 也是能够读取这些 XML 文件并识别里面的内容的。
  • @EnableAutoConfiguration 注解:开启自动配置。这样 Spring Boot 在启动时就可以自动加载所有配置文件和配置类了。
  • @ComponentScan 注解:启用组件扫描器。这样项目才能自动发现并创建各个组件的 Bean,包括 Web 控制器(@Controller)、服务(@Service)、配置类(@Configuration)和其他组件(@Component)。

注意:

一个项目可以有多个启动类,但这样的代码毫无意义。一个项目应该只使用一次@ SpringBootApplication 注解。

@SpringBootApplication 有一个使用要求:只能扫描底层包及其子包中的代码。底层包就是启动类所在的包。如果启动类在 com.spark.springbootlearning 包下,其他类应该写在 com.spark.springbootlearning 包或其子包中,否则无法被扫描器找到,就等同于无效代码。例如在图3.1和图3.2中,Controller类所在的位置可以被扫描到。而在图3.3和图3.4中,Controller类的位置就无法被扫描到了。

2.2 Bean 的注册和获取

Bean 指的是由 Spring Boot 容器管理的对象。Bean 是根据 Spring Boot 配置文件中的数据信息予以创建的。如果把 Spring Boot 容器看作是一个大工厂,那么 Bean 就相当于这个工厂生成的产品。

2.2.1 Bean 与依赖注入

在明确了什么是 Bean 后,还需要明确另外一个非常重要的概念:依赖注入

在面向对象程序设计中,对象和对象之间存在一种叫作“依赖”的关系。简单来说,依赖关系就是在一个对象中需要用到另外一个对象,即对象中存在一个属性,该属性是另外一个类的对象。

例如,在一个 B 类对象中,有一个 A 类的对象 a,那么就可以说 B 类的对象依赖于对象 a。而依赖注入就是基于这种“依赖关系”而产生的。

Spring Boot 在创建一个对象的过程中,会根据“依赖关系”,把这个对象依赖的对象注入其中,这就是所谓的“依赖注入”。

掌握了 Bean 和依赖注入的概念后,再结合下图理解两个过程:

  1. 「 Bean 的注册 」:Spring Boot 能够自动寻找程序开发人员已经创建好的 Bean,并将其保存在 Spring Boot 容器中,这个过程被称作 Bean 的注册。
  2. 「 Bean 的注入 」:把 Spring Boot 容器中的 Bean 赋值给某个尚未被赋值的成员变量,这个过程被称作 Bean 的注入。

在这里插入图片描述

当 Spring Boot 项目被启动时,Spring Boot 首先会自动扫描所有的组件,然后注册所有的 Bean,最后把这些 Bean 注入各自的使用场景当中。下面通过一个实例,演示「 注册 Bean 」和「 注入 Bean 」的这两个过程。

  1. 创建用于注册 Bean 的组件类:BeanComponent

在这里插入图片描述

BeanComponent 类被 @Component 标注,表示这个类是一个组件类。类中只有一个 name() 方法,并且被 @Bean 标注,表示这个方法返回的对象被注册成了 Bean,并将其放到 Spring Boot 容器中。

  1. 创建 BeanTestController 控制器类

在这里插入图片描述

BeanTestController 类被 @RestController 标注,表示这个类是一个负责页面跳转的控制器,会直接返字符串结果。类中:

  • name 属性被 @Autowired 标注,表示这个属性的值由 Spring Boot 注入。
  • showName() 方法被 @RequestMapping(“/bean”) 标注,表示该方法映射“/bean”地址,并将 name 的值展示在页面中。
  1. 启动项目,打开浏览器,访问 http://127.0.0.1:8080/bean 地址,可以看到下图所示的结果:

在这里插入图片描述

页面中显示 “BeanComponent”,但 BeanTestController 类中没有出现任何 “BeanComponent” 的字样,这个值是哪来的呢?“BeanComponent” 这个值出现在 BeanComponent 类的 name() 方法的返回值中。当 Spring Boot 项目被启动时,扫描器发现了 BeanComponent 类,并在该类下发现了被 @Bean 标注的方法,于是把该方法返回的对象注册成 Bean,再放到 Spring Boot 容器中。与此同时,扫描器也发现了 BeanTestController 类,发现这个类有一个 name 属性需要被注入值,Spring Boot 便在 Spring Boot 容器中查找有没有类型相同、名称匹配的 Bean,于是就找到了 name() 方法返回的字符串“BeanComponent”,便将 “BeanComponent” 赋给了 name 属性。当前端发来请求时,showName() 方法便将 name 的值(也就是“BeanComponent”)展示在了网页中。这就是一个「 注册 Bean 」和「 注入 Bean 」的例子。

2.2.2 注册 Bean

注册 Bean 需要用到 @Bean 注解,该注解用于标注方法,表示方法的返回值是一个即将进入 SpringBoot 容器中的 Bean。下面介绍 @Bean 注解的具体用法。

📄 1. 让 Spring Boot 发现 @Bean

如果想让 @Bean 注解生效,那么被标注的方法所在的类必须能够被 Spring Boot 的组件扫描器扫描到。

以下几个注解都可以让被标注的方法所在的类被扫描到:

注解说明
@Configuration声明配置类
@Controller声明控制器类
@Service声明服务接口或类
@Repository声明数据仓库
@Component如果不知道类属于什么模块,就用这个注解将类声明成组件。推荐使用此注解

如果不使用上面这 5 个注解,那么也可以用 @Import 注解将 @Bean 所在类的主动注册给 Spring Boot。

例如,我们修改刚才的代码,删除 BeanComponent 类上的 @Component 注解,代码如下:

在这里插入图片描述

在 Spring Boot 项目的启动类中,通过使用

@Import({com.mr.component.BeanComponent.class})

声明启动类,让项目启动时自动导入 BeanComponent 类,代码如下:

在这里插入图片描述

这样,当 Spring Boot 项目被启动时,BeanComponent 类中的 @Bean 也可以被注册到 Spring Boot 容器中(这里就不运行了,你可以自己测试)。

如果想要导入多个指定的类,@Import 的语法如下(注意圆括号和大括号的位置):

​​​​@Import({A.class, B.class, C.class})​​

📄 2. @Bean的使用方法

@Bean 注解有很多属性,其核心源码如下:

public @interface Bean {@AliasFor("name")String[] value() default {};@AliasFor("value")String[] name() default {};boolean autowireCandidate() default true;String initMethod() default "";String destroyMethod() default "(inferred)";
}

下面分别介绍这几个属性的用法:

  1. valuename 这两个属性的作用是一样的:就是给 Bean 起别名,让 Spring Boot 可以区分多个类型相同的 Bean。给 Bean起别名的语法如下:
​​​​@Bean("goudan")
​​​​@Bean(value = "goudan")
​​​​@Bean(name = "goudan")
​​​​@Bean(name = {"goudan", "GouDan", "Golden"})  // 同时给一个 Bean 起多个别名​​

如果没有给 Bean 起任何别名的话,那么 @Bean 注解会默认将方法名作为别名,例如:

​​​​@Bean
​​​​public String name() {
​​​​    return "Marco";
​​​​}​​

上面代码等同于:

​​​​@Bean(name = "name")
​​​​public String name() {
​​​​    return "Marco";
​​​​}​​
  1. autowireCandidate 属性:表示 Bean 是否采用默认的自动匹配机制,默认值为 true,如果将其赋值为 false,这个 Bean 就不会被默认的自动匹配机制匹配到,只能通过「使用别名的方式」匹配到

比如,我们修改刚才的例子,代码如下:

在这里插入图片描述

BeanComponent 类中创建了两个方法,返回值类型均为 String。otherName() 方法定义了别名,并且 autowireCandidate 的值为 false,表示 Spring 在匹配 Bean 时会自动忽略 otherName() 方法的返回值。

下面再来看一下注入的代码。修改 BeanTestController 控制器类,代码如下:

在这里插入图片描述

BeanTestController 类定义了一个 name 属性,该属性使用 @Resource 标注,表示这个属性由 Spring 自动匹配并注入值。启动项目,打开浏览器访问 http://127.0.0.1:8080/bean 地址,看一下 name 被注入的值是什么:

在这里插入图片描述

name 的值为 “BeanComponent”,即使 Spring 容器中有两个 String 类型的 Bean,但值为 “Marco” 的 Bean 拒绝自动匹配机制,所以 name 只能得到 “BeanComponent” 这个值。

如果想要得到 “Marco” 这个 Bean,就需要在注入时指定 Bean 的别名。例如使用 @Resource 注解读取别名为 “In” 的 Bean,关键代码如下:

在这里插入图片描述

这样,name 取的值就是别名为 “In” 的 Bean 的值。重启 Spring Boot 项目,并且重新访问地址 http://127.0.0.1:8080/bean 后,就可以看到网页上显示的值变成了 “Marco”,效果如下:

在这里插入图片描述

  1. initMethod 属性:用于指定 Bean 初始化时会调用什么方法。
  2. destroyMethod 属性:用于指定 Bean 被 Spring 销毁时会调用什么方法,两个属性的值均为 Bean 对象的方法名。

2.2.3 获取 Bean

获取 Bean 就是在类中创建一个属性(可以是 private 属性),通过为属性添加注解,让 Spring Boot 为这个属性注入 Bean。

可以获取 Bean 的注解有3个:@Autowired、@Resouce 和 @Value

这 3 个注解只能在可以被扫描到的类中使用。下面分别介绍这 3 个注解的用法。

📄 @Autowired

@Autowired 注解可以自动到 Spring 容器中寻找名称相同或类型相同的 Bean。例如,注册 Bean 的方法为:

​​​​@Bean
​​​​public String author() {
​​​​    return "Marco";
​​​​}​​

获取这个 Bean 的代码可以写成:

​​​​@Autowired
​​​​String author;

@Autowired 可以自动匹配与属性同名(即别名为 “author”)的 Bean。如果匹配不到同名的 Bean,@Autowired 可以自动匹配类型相同的 Bean。例如,注册方法不变,获取 Bean 的代码为:

​​​​@Autowired
​​​​String name;​​

即使这么写,name 也可以获得 “Marco” 这个值,因为两者数据类型是相同的。

但要注意,当 Spring Boot 容器中仅有一个该类型的 Bean 时,@Autowired 才能匹配成功。如果存在多个该类型的 Bean,Spring 就不知道应该匹配哪个 Bean 了,项目就会抛出异常。例如,注册 Bean 的方法如下:

​​​​@Bean
​​​​public String author() {
​​​​    return "Marco";
​​​​}​​

​​​​@Bean
​​​​public String dev() {
​​​​    return "Superman";}

现在容器中有两个 String 类型的 Bean,然后获取 Bean 的代码为:

​​​​@Autowired
​​​​String name;​​

启动项目后会抛出如下异常日志:

***************************
APPLICATION FAILED TO START
***************************Description:Field name in com.spark.springbootlearning.controller.BeanTestController required a single bean, but 2 were found:- author: defined by method 'author' in class path resource [com/spark/springbootlearning/component/BeanComponent.class]- dev: defined by method 'dev' in class path resource [com/spark/springbootlearning/component/BeanComponent.class]This may be due to missing parameter name information

IDEA 代码也会有波浪线报错提示:

在这里插入图片描述

这个异常日志的意思是:程序需要自动匹配一个独立的 Bean,却找到了两个符合条件的 Bean。其中,一个 Bean 的别名叫“author”,另一个 Bean 的别名叫“dev”。程序因为不知道哪个 Bean 是当前需要的,所以就停止了。

在这种因同时存在多个 Bean 而无法自动匹配的情况下,就需要指定 Bean 的别名以获取 Bean。

指定别名有两种方式:

  • 将类属性名改成 Bean 的别名。如果 Bean 的别名叫 “author”,@Autowired 标注的属性名也叫 “author”。
  • 使用 @Qualifier 注解。@Qualifier 注解有一个 value 属性,用于指定要获取的 Bean 的别名。可以与 @Autowired 配套使用。例如,获取别名为 “dev” 的 Bean,代码如下:
​​​​@Autowired
​​​​@Qualifier("dev")
​​​​String name;​​

📄 @Resource

@Resource 注解的功能与 @Autowired 类似:@Resouce 注解自带 name 属性,可直接指定 Bean 的别名。其中,name 属性的默认值为空字符串,表示自动将被标注的属性名作为 Bean 的别名。

例如,获取别名为 “author” 的 Bean,可以有 3 种写法:

第一种写法:

​​​​@Resource(name="author")
​​​​String name;

第二种写法:

@Resource
​​​​String author;  // 属性名就叫 author​

第三种写法:虽然可以执行,实际与第一种写法是一样的,不推荐这样写

​​​​@Resource(name="")
​​​​String author;​​

注意:

如果使用 @Autowired 注入 Object 类型的 Bean 时,抛出了 org.springframework.beans.factory. NoUniqueBeanDefinitionException:No qualifying bean of type ‘java.lang.Object’ available 异常,就将 @Autowired 换成 @Resource。

📄 @Value

@Value 注解可以动态地向属性注入值。@Value 有3种语法,分别是:

  1. 注入常量值。

下面的语法会让 name 的值等于 “author” 这个字符串,例如:

​​​​@Value("author")
​​​​String name;
  1. 注入 Bean。

使用 “#{Bean别名}” 格式可以注入指定别名的 Bean,其效果类似于 @Resource(name=“Bean别名”),例如:

@Value("#{author}")
​​​​String name;​​
  1. 注入配置文件中配置信息的值。

使用“${配置项}”格式可以注入 application.properties 文件中指定名称的配置信息的值,例如:

​​​​@Value("${author}")
​​​​String name;​​

注意:

如果配置文件中没有该项则会抛出 BeanCreationException 异常。

2.3 为Spring Boot项目添加依赖

在 Spring Boot 项目开发的过程中,有些依赖需要程序开发人员手动添加。本节将对如何手动为 Maven 项目添加依赖进行讲解。

2.3.1 在 pom.xml 文件中添加依赖

pom.xml 是Maven构建项目的核心配置文件,程序开发人员可以在此文件中为项目添加新的依赖,新的依赖将被添加到 <dependencies> 标签的子标签中,添加依赖的格式如下:

​​​​<dependency>
​​​​    <groupId>所属团队</groupId>
​​​​    <artifactId>项目ID</artifactId>
​​​​    <version>版本号</version>
​​​​    <scope>使用范围(可选)</scope>
​​​​</dependency>

注意:

在 pom.xml 文件中,<dependency> 标签是 <dependencies> 标签的子标签。

例如,Spring Boot 项目自带的 Web 依赖和 JUnit 单元测试依赖在 pom.xml 中填写的位置如图所示。

在这里插入图片描述

程序开发人员只需要仿照这种格式在 标签内部添加其他依赖,然后保存 pom.xml 文件,Maven 就会自动下载依赖中的 jar 文件并自动引入项目中。

2.3.2 如何查找依赖的版本号

如果程序开发人员不知道依赖的 ID 和版本,可以到 MVNrepository 或阿里云云效 Maven 中去查找。

  1. MVNrepository 的官网地址为 https://mvnrepository.com/ ,查询结果如下图所示:

在这里插入图片描述

  1. 阿里云云效 Maven 虽然不会直接显示 XML 文本,但可以看到 groupId、artifactId 和 version 这3个值,效果如下图所示:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024最新gewechat开发微信机器人教程说明

简介&#xff1a;本文将指导你如何搭建一个微信机器人&#xff0c;通过接入gewe框架实现智能回复与聊天功能。我们将从基础设置开始&#xff0c;逐步讲解如何配置机器人&#xff0c;并通过实例展示其实际应用。 随着人工智能技术的不断发展&#xff0c;智能机器人已经成为我们…

Hadoop 常用生态组件

Hadoop核心组件 安装 Hadoop 时&#xff0c;通常会自动包含以下几个关键核心组件&#xff0c;特别是如果使用了完整的 Hadoop 发行版&#xff08;如 Apache Hadoop、Cloudera 或 Hortonworks 等&#xff09;。这些组件构成了 Hadoop 的核心&#xff1a; 1. HDFS&#xff08;H…

基于python+django+vue的旅游景点数据分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

高密度EEG人脑成像:技术与应用

摘要 EEG是一种非侵入性的人脑神经活动测量技术。随着数字技术的进步&#xff0c;EEG分析已从定性分析幅值和频率调制发展到全面分析记录信号的复杂时空特征。EEG能够在亚秒级的时间范围内测量神经过程&#xff0c;但其空间分辨率较低&#xff0c;这使得难以准确可靠地定位EEG…

批量发送邮件:性能优化与错误处理深度解析

目录 一、批量发送邮件的基础概述 1.1 批量发送邮件的定义 1.2 邮件发送流程 二、性能优化策略 2.1 发送速率控制 2.2 队列管理 2.3 动态IP池管理 2.4 智能调度 三、错误处理机制 3.1 暂时性发送错误处理 3.2 永久性发送错误处理 3.3 邮件反馈收集与分析 四、案例…

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(五)-聚合

聚合 聚合基于Query结果的统计&#xff0c;执行过程是搜索的一部分&#xff0c;Onesearch支持0代码构建聚合&#xff0c;聚合目前完全在引擎层 0代码聚合 上图是聚合的配置&#xff0c;包括2个pdm文档聚合统计 termsOfExt term桶聚合&#xff0c;统计ext&#xff0c;如&…

18923 二叉树的直径

### 思路 1. **构建二叉树**&#xff1a; - 使用输入数据构建二叉树。 - 使用一个数组或哈希表来存储每个节点的子节点。 2. **计算直径**&#xff1a; - 使用深度优先搜索&#xff08;DFS&#xff09;计算每个节点的深度。 - 计算每个节点的左子树和右子树的深度…

neo4j关系的创建删除 图的删除

关系的创建和删除 关系创建 CREATE (:Person {name:"jack"})-[:LOVE]->(:Person {name:"Rose"})已有这个关系时&#xff0c;merge不起效果 MERGE (:Person {name:"Jack" })-[:LOVE]->(:Person {name:"Rose"})关系兼顾节点和关…

机器学习笔记(一)初识机器学习

1.定义 机器学习是一门多学科交叉专业&#xff0c;涵盖概率论知识&#xff0c;统计学知识&#xff0c;近似理论知识和复杂算法知识&#xff0c;使用计算机作为工具并致力于真实实时的模拟人类学习方式&#xff0c;并将现有内容进行知识结构划分来有效提高学习效率。 机器学习有…

开源ids snort (windows版)

Snort-IPS-on-Windows-main资源-CSDN文库 GitHub - eldoktor1/Snort-IPS-on-Windows: A comprehensive guide to installing and configuring Snort IPS on Windows, ensuring robust network security 手动打造Snortbarnyard2BASE可视化告警平台 - FreeBuf网络安全行业门户 …

银河麒麟桌面操作系统如何添加WPS字体

银河麒麟桌面操作系统如何添加WPS字体 1、使用场景2、操作方法步骤一&#xff1a;下载字体文件步骤二&#xff1a;打开终端步骤三&#xff1a;进入字体文件所在目录步骤四&#xff1a;拷贝字体文件到WPS字体目录步骤五&#xff1a;更新字体缓存步骤六&#xff1a;重启WPS Offic…

【PAM】Linux登录认证限制

PAM&#xff08;Pluggable Authentication Modules&#xff0c;可插拔认证模块&#xff09;是一种灵活的认证框架&#xff0c;用于在 Linux 和其他类 Unix 系统上管理用户的身份验证。PAM 允许系统管理员通过配置不同的认证模块来定制应用程序和服务的认证方式&#xff0c;而不…

基于gorm.io/sharding分表中间件使用案例

项目背景 项目中需要用到mysql的分表场景&#xff0c;调研了一些常用的分库分表中间件&#xff0c;比如&#xff0c;mycat&#xff0c;小米的Gaea&#xff0c;这两个中间件太重了&#xff0c;学习成本较大&#xff0c;另外mycat不是go写的。我们需要一个轻量级的go版本的分表中…

Tomcat 乱码问题彻底解决

1. 终端乱码问题 找到 tomcat 安装目录下的 conf ---> logging.properties .修改ConsoleHandler.endcoding GBK &#xff08;如果在idea中设置了UTF-8字符集&#xff0c;这里就不需要修改&#xff09; 2. CMD命令窗口设置编码 参考&#xff1a;WIN10的cmd查看编码方式&am…

网络安全的方方面面

目录 一、网络安全概述二、数据加密三、消息完整性与数字签名四、身份认证五、密钥分发中心(KDC)与证书认证(CA)六、防火墙与入侵检测系统七、网络安全协议八、网络安全攻防 -- 黑客攻击简要流程九、网络安全常用术语 一、网络安全概述 网络安全的基本特征&#xff1a;相对性、…

稳了,搭建Docker国内源图文教程

大家好&#xff0c;之前分享了我的开源作品 Cloudflare Workers Proxy&#xff0c;它的作用是代理被屏蔽的地址&#xff0c;理论上支持代理任何被屏蔽的域名&#xff0c;使用方式也很简单&#xff0c;只需要设置环境变量 PROXY_HOSTNAME 为被屏蔽的域名&#xff0c;最后通过你的…

关于LlamaIndex 的几种索引方式介绍

每个索引的工作原理 本指南介绍每个索引如何与图表配合使用。 一些术语&#xff1a; Node&#xff1a;对应于 Document 中的一段文本。LlamaIndex 接收 Document 对象&#xff0c;并在内部将它们解析/分块为 Node 对象。Response Synthesis&#xff1a;我们的模块&#xff0…

案例研究丨国控星鲨利用DataEase释放数据潜能,重塑业务视野

国药控股星鲨制药&#xff08;厦门&#xff09;有限公司&#xff08;以下简称为国控星鲨&#xff09;始创于1952年&#xff0c;前身为厦门鱼肝油厂&#xff0c;距今已经有70余年历史&#xff0c;是国家商务部认定的“中华老字号”企业。2011年&#xff0c;国药控股与厦门轻工集…

ChatGPT Sidebar 浏览器插件配置指南

随着聊天机器人技术的不断进步&#xff0c;越来越多的人开始依赖这些强大的工具来提高工作效率、获取信息和解决问题。OpenAI 的 ChatGPT 是其中最受欢迎的聊天机器人之一。为了方便用户在浏览网页时随时与 ChatGPT 互动&#xff0c;开发者们设计了一款名为 ChatGPT Sidebar 的…

Maven的详细解读和配置

目录 一、Maven 1.1 引言 1.2 介绍 1.3 下载安装 1.3.1 解压 1.3.2 配置环境变量 1.3.3 测试 1.4 仓库[了解] 1.5 Maven配置 1.5.1 修改仓库位置 1.5.2 设置镜像 二、IDEA - MAVEN 2.1 idea关联maven 2.2 为新项目设置 2.2 创建java项目[重点] 2.3 java项目结构…