1. SpringBoot3 基础
文章目录
- 1. SpringBoot 概述
- 2. SpringBoot 入门
- 3. SpringBoot 配置文件
- 3.1 SpringBoot 配置文件基本使用
- 3.2 yml 配置文件
- 4. SpringBoot 整合 Mybatis
- 5. Bean 管理
- 5.1 Bean 扫描
- 5.2 Bean 注册
- 5.3 注册条件
- 6. 组合注解
- 7. 自动配置原理
- 8. 自定义 Starter
1. SpringBoot 概述
在 SpringBoot 之前,通过 Spring Framework 整合各种子项目,来构建 Spring应用程序:
传统方式构建 spring 应用程序,需要挨个导入依赖,项目配置繁琐:
SpringBoot 是 Spring 提供的一个子项目,用于快速构建 Spring 应用程序:
SpringBoot 的特性,用于简化开发:
(1) 起步依赖:本质上就是一个 Maven 坐标,整合了完成一个功能需要的所有坐标。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
(2) 自动配置:遵循约定大约配置的原则,在 boot 程序启动后,一些 bean 对象会自动注入到 ioc 容器,不需要手动声明,简化开发。
比如现在要整合 mybatis:
- 传统的方法,首先要整合 mybatis 依赖,还要声明两个 bean 对象。
- 使用 SpringBoot 整合 mybatis 时,只需要引入 mybatis 起步依赖,因为起步依赖会自动引入前述的两个 bean 对象。
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.0</version>
</dependency>
(3) 其他特性
- 内嵌的 Tomcat、Jetty(无需部署WAR文件)
- 外部化配置
- 不需要 XML 配置,只需在 properties / yml 中进行少量的配置
2. SpringBoot 入门
需求:使用 SpringBoot 开发一个 web 应用,浏览器发起请求 /hello
后,给浏览器返回字符串 hello world~
。
使用 SpringBoot 后,不必再像之前那样繁琐,只需以下两个步骤:
下面从用 idea 创建工程开始,实现上面的需求:
(1) 创建 springboot 工程
(2) 下面来看一下新创建的 SpringBoot 工程中有什么内容。
pom.xml 文件中有自动导入的起步依赖:
@SpringBootApplication
标识当前类是 SpringBoot 启动类,是程序的入口:
资源目录:
(3) 新建 controller 目录,编写 HelloController
(4) 运行 main 方法
当 main 方法运行时,SpringBoot 工程就会启动,它内置的 tomcat 也会自动启动,并且把 Controller 这样的资源部署好,这样就能够通过浏览器访问了。
3. SpringBoot 配置文件
3.1 SpringBoot 配置文件基本使用
SpringBoot 提供了多种属性配置方式,一种是 properties 配置文件,另一种是 yml / yaml 配置文件(yml 和 yaml 只是名字不同,没其他区别)。
首先来看 properties 配置文件,在使用 Spring Initializer 创建 SpringBoot 工程时,会自动生成application.properties
配置文件。
我们可以在其中配置一些信息,且该配置文件是 SpringBoot 可以自动识别的。下面这个链接中给出了在该配置文件中可以配置的内容:
docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties
可以看到,这些配置都有一些默认值。如:tomcat 启动时默认绑定 8080 端口,当前项目的虚拟目录默认没有配置。
对于这些默认配置,我们可以在 application.properties
进行修改:
修改后再次启动 SpringBoot 工程:
在浏览器中访问:
下面简单介绍 yml / yaml 配置文件(只是名字不同,没其他区别,常写作 yml)。
该配置文件与 properties 配置文件的内容相同,只是格式不同。properties 配置文件的层级关系通过 .
来体现,yml 配置文件的层级关系通过 换行和缩进
来体现。
创建 yml 文件,写入配置信息:
启动工程:
浏览器访问:
3.2 yml 配置文件
在实际开发中,yml 配置文件与 properties 配置文件相比,书写格式相对清晰,所以更常用。下面对 yml 配置文件展开详细介绍。
yml 配置文件在实际开发中有两种使用方式:
(1) 书写三方技术所需的配置信息
例如,程序中要使用 redis,要做的就是:① 引入 redis 起步依赖;② 根据 redis文档编写配置信息。起步依赖会在工程启动之后,自动获取编写的配置信息,所以无需手动获取。后续会详细介绍 SpringBoot 如何整合三方技术。
(2) 书写自己程序所需的自定义配置信息(本节重点)
举个例子:在使用阿里云对象服务时,Java 代码中会有一些服务相关的配置信息:
如果这样,配置信息就跟 Java 代码耦合了。一旦配置信息发生变化,就必须去修改 Java 代码,重新进行编译、测试、打包、部署等操作,十分耗时。在实际开发中,常常将配置信息书写到配置文件中。这样,当配置文件中的信息发生改变时,重启服务器即可,不需要重新编译、测试、打包、部署等操作。
当配置信息书写到配置文件中时,Java 代码想要获取这些配置信息,就要通过代码来手动获取,因为不能自动获取。
书写配置信息
下面是发送邮件的代码所用到的一个实体类,其中有一些配置信息,需要将它们抽取到 properties 或 yml 配置文件中:
上面的配置文件中的键为什么要用 email 做前缀? 因为其他地方也可能有 user、code 等这种键名,加上前缀是为了防止冲突。
注意 yml 文件的书写格式:
- 值前边必须有空格,作为分隔符
- 缩进表示层级关系,相同的层级左侧对齐
扩展:数组配置项的书写格式
hobbies:- "eat"- "drink"- "play"
获取配置信息
方法 1: 在 Java 代码的成员变量上添加 @Value("${键名}")
方法 2: 使用 @ConfigurationProperties(prefix="前缀")
注解,同时成员变量名与配置文件中的键名保持一致。(更简洁)
4. SpringBoot 整合 Mybatis
Spring 整合 mybatis 时,需要引入 mybatis 依赖以及 mybatis 和 spring 的整合依赖,此外还需要配置一些 bean 对象,如:SqlSessionFactoryBean、MapperScannerConfigurer、Datasource。
上面的过程相对繁琐,SpringBoot提供了更为简洁的方式:
(1) 引入 mybatis 起步依赖:相当于将 mybatis 依赖以及 mybatis 和 spring 的整合依赖全部引进来了。同时,该起步依赖会自动将 bean 对象注入 IOC 容器中,也就是前述的 bean 对象都无需再手动配置。
(2) 配置 yml 文件:让 mybatis 去操作数据库。
接下来就可以正常地去编写 Controller、Service、Mapper。当浏览器访问 Controller 时,Controller 去访问 Service,Service 去访问 Mapper,Mapper 最终去操作数据库。
案例:查询 User 表中指定 id 的数据,相应给浏览器
(1) 创建数据库表
create database if not exists mybatis;use mybatis;create table user(id int unsigned primary key auto_increment comment 'ID',name varchar(100) comment '姓名',age tinyint unsigned comment '年龄',gender tinyint unsigned comment '性别, 1:男, 2:女',phone varchar(11) comment '手机号'
) comment '用户表';insert into user(id, name, age, gender, phone) VALUES (null,'白眉鹰王',55,'1','18800000000');
insert into user(id, name, age, gender, phone) VALUES (null,'金毛狮王',45,'1','18800000001');
insert into user(id, name, age, gender, phone) VALUES (null,'青翼蝠王',38,'1','18800000002');
insert into user(id, name, age, gender, phone) VALUES (null,'紫衫龙王',42,'2','18800000003');
insert into user(id, name, age, gender, phone) VALUES (null,'光明左使',37,'1','18800000004');
insert into user(id, name, age, gender, phone) VALUES (null,'光明右使',48,'1','18800000005');
(2) 在 pom.xml 中添加依赖
(3) 配置数据源信息
(4) 到这里,SpringBoot 整合 mybatis 就完成了,下面开始各个类的编写。
① pojo 类
package com.itheima.springbootmybatis.pojo;public class User {// 与数据库表中的字段名称是一一对应的private Integer id;private String name;private Short age;private Short gender;private String phone;public User() {}public User(Integer id, String name, Short age, Short gender, String phone) {this.id = id;this.name = name;this.age = age;this.gender = gender;this.phone = phone;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Short getAge() {return age;}public void setAge(Short age) {this.age = age;}public Short getGender() {return gender;}public void setGender(Short gender) {this.gender = gender;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", gender=" + gender +", phone='" + phone + '\'' +'}';}
}
② Mapper (数据层)
@Mapper
public interface UserMapper {@Select("select * from user where id = #{id}")public User findById(Integer id);
}
③ Service 接口和实现类 (业务层)
public interface UserService {public User findById(Integer id);
}
@Service
public class UserServiceImpl implements UserService {@Autowired //按类型注入IOC中的bean对象private UserMapper userMapper;@Overridepublic User findById(Integer id) {return userMapper.findById(id);}
}
④ Controller (表现层)
@RestController
public class UserController {@Autowired private UserService userService;@RequestMapping("/findById")public User findById(Integer id){return userService.findById(id);}
}
运行结果:
5. Bean 管理
5.1 Bean 扫描
在 SpringBoot 之前,需要用以下方式来扫描 Bean:
但是,使用 SpringBoot 时,两种方法都没有用到,却依然能扫描到我们写的 Controller、Service 等等,这是因为 SpringBoot 的启动类上有 @SpringBootApplication
注解,且该注解整合了 @ComponentScan
注解:
需要要注意的是,该注解并没有指定要扫描的包路径,那么 Controller、Service 等是如何被扫描到的呢?
如果不指定扫描路径,默认扫描的是添加了该注解的类所在的包及其子包。
在此工程中,默认扫描的包就是 springbootmybatis。如果将 Controller 移出该包,就扫描不到它了:
此时,如果还想要 Controller 被扫描到,就要在启动类上添加 @ConponentScan
注解,指明要扫描的包:
5.2 Bean 注册
Bean 注册:把 Bean 对象注册到 IOC 容器中。
可以在类上添加下面的注解,从而把该类的对象注册到 IOC 容器中:
用 @Controller
、@Service
、@Repository
的地方也可以用 @Component
,只是用这三个注解能够增强可读性。
但是针对三方的类(不是自定义的),就不能再使用这些注解将其 Bean 对象注入到 IOC 容器。那该怎么办呢?Spring 提供了 @Bean
和 @Import
两个注解来解决这个问题。
在使用这两个注解之前,首先要做一些准备工作:
pom.xml 文件:并没有引入 web 起步依赖,而是引入了 SpringBoot 核心依赖。因为在本节不做 web 的开发,只是注册 bean 对象。用 web 起步依赖的话,每次都要启动 tomcat,比较麻烦。
在 pom.xml 中导入一个三方 jar 包
我们的目标是将该 jar 包中的 Country 和 Province 的 bean 对象注入到 IOC 容器中。
(1) 用 @Bean 将三方 bean 对象注入 IOC 容器
用 @Bean
将第三方 bean 对象注入到 IOC 容器,可以通过在启动类中声明一个方法来实现。该方法有 @Bean
注解,并返回一个创建好的对象。当 Spring 解析到该方法时,就会将该方法的返回值自动注入 IOC 容器。
如果能将上面的 bean 对象从 IOC 容器中拿出来,就能够验证操作有效。
验证方法:启动类中的 SpringApplication.run() 方法用于启动工程,同时也会返回 Spring 初始化好的容器,所以可以通过该方法接收到 IOC 容器,进而拿到刚刚放入的 bean 对象。
输出结果:
Country{name='null', system='null'}
但是,启动类中写其他的功能不是一种好的编程习惯,所以以这种方式将三方 bean 注入 IOC 容器不推荐。
如果要注册第三方的 bean,建议在配置类(用@Configuration
标识)中集中注册。
具体就是,在配置类中声明与启动类中相同的方法(带 @Bean
注解)就能将该方法的返回值注入到 IOC 容器中了。需要注意的是,该配置类需要放到启动类所在的包或其子包下(为了能被扫描到)。
如果想要在 IOC 中注入多个三方 bean 对象,声明类似的方法即可。
还是用与前面形同的方法进行验证:
输出结果:
Country{name='null', system='null'}
Province{name='null', direction='null'}
在启动类中获取已经注入 IOC 容器中的 bean 对象时,也可以通过 bean 对象的名称来获取。bean 对象的默认名称是将其注入到 IOC 容器的方法的名称。
System.out.println(context.getBean("province"));
当然,bean 对象的名称也可以指定:
此时,启动类中,根据名称获取 bean 对象的操作应为:
System.out.println(context.getBean("aa"));
如果方法内部需要使用 IOC 容器中已经存在的 bean 对象,只需在方法上声明即可,Spring 会自动注入:
输出结果:
province: Country{name='null', system='null'}
Country{name='null', system='null'}
Province{name='null', direction='null'}
(2) 用 @Import 将三方 bean 对象注入 IOC 容器
只要在启动类上添加 @Import
注解,导入一个 xxx 类,Spring 就会把 xxx 对应的 bean 对象注入到 IOC 容器中。(相当于手动扫描)
xxx 类可以是一个普通类,也可以是一个配置类。在实际开发中,通常是配置类或 ImportSelector 接口的实现类。
为了演示 @Import
的作用,首先将 Controller 移出启动类的扫描范围:
CommonConfig.java:
① Import 配置类
如果有多个这样的配置类,可以把多个配置类放到一个数组中:
@Import({CommonConfig1.class, CommonConfig2.class, CommonConfig3.class})
但是,如果类似的配置文件过多,就会使这段代码很臃肿。此时,可以使用 ImportSelector 接口的实现类来解决。
② Import ImportSelector
接口的实现类
首先要定义一个类去实现 ImportSelector 接口,并重写其中的 selectImports() 方法。
selectImports() 方法返回一个字符串数组,每个元素就是要注入到 IOC 容器中的 bean 对象全类名。
需要注意的是,SpringBoot 会自动调用 selectImports() 方法,得到含全类名的数组,并把这些类的 bean 对象注入到 IOC 容器中。
此时,就不再 Import 配置类了,而是 ImportSelector 接口的实现类:
这样,工程启动之后,就会扫描到 @Import 注解,再去找到 CommonImportSelector 这个实现类,自动执行 selectImports() 方法,得到 bean 对象的全类名,并将对应的 bean 对象注入到 IOC 容器中。
在实际开发中,selectImports() 方法中的全类名数组并不是写死的,而是从配置文件中获取到的。这样的话,有哪些 bean 对象需要注入,就只需要将其对应的全类名写在配置文件里。下面介绍具体操作:
首先,新建 common.imports 文件,写入 bean 对象对应的全类名(如果有多个,就写多行):
然后,在 CommonImportSelector 类中读取 common.imports 文件中的内容:
public class CommonImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//读取配置文件的内容List<String> imports = new ArrayList<>();//通过类加载器读取配置文件InputStream is = CommonImportSelector.class.getClassLoader().getResourceAsStream("common.imports");//下面看不懂,去补一下java基础中的反射和io流//为了方便使用,将输入流封装一下BufferedReader br = new BufferedReader(new InputStreamReader(is));String line = null;try {while ((line = br.readLine()) != null){imports.add(line);}} catch (IOException e) {e.printStackTrace();} finally {if (br != null){try {br.close();//释放资源} catch (IOException e) {e.printStackTrace();}}}return imports.toArray(new String[0]);}
}
5.3 注册条件
可以发现,之前的代码输出的 Country 对象和 Province 对象的属性都为 null,这是因为没有初始化。如何对其进行初始化呢?可以在 CommonConfig.java 中通过各自的 setter 方法直接赋值,但是这样的话,值就又写到了 java 代码中,值发生改变就要修改 java 代码,从而需要重新编译等工作。
规范的写法是:将这些值写到配置文件中:
再用 @Value
注解将配置文件中的值注入到 java 代码的相应变量中
【注】@Value 不仅可以添加到成员变量上,也可以添加到参数列表上
此时如果将配置文件中的内容全部注释掉,代码就会因无法解析变量而报错。如果我们想要:配置文件里有值,就注入变量;没有值,就不注入。该怎么办呢?
要达到这种效果,需要用到注册条件相关知识。
SpringBoot 提供了设置注册生效条件的注解 @Conditional
,可以借助该注解设置 Bean 注册的条件。但是该注解的使用较为繁琐,SpringBoot 提供了其衍生注解:
(1) @ConditionalOnProperty
注解:配置文件中存在对应的属性,才将该 bean 注入 IOC 容器
(2) @ConditionalOnMissingBean
注解:当不存在某类型的 bean 时,才将该 bean 注入 IOC 容器
(3) @ConditionalOnClass
注解:当前环境存在某个类时,才将该 bean 注入 IOC 容器
获取 DispatcherServlet 类的全类名的方式:按两下 Shift ➡ 输入类名 DispatcherServlet ➡ 选择 Classes ➡ 进入类。
在类名上右键,Copy ➡ Copy Reference
可以看到,当前的工程没有引入 web 起步依赖:
所以就不能在 IOC 容器中获取到 Province 的 bean 对象,只有添加了 web 起步依赖,当前环境才会有 DispatcherServlet 类,进而向 IOC 容器注入 Province 的 bean 对象。
以上三个注解,经常会在自定义 starter 或 SpringBoot 源码中看到。
6. 组合注解
定义一个注解类
这样就能把 @Import(CommonImportSelector.class)
注解整合到 @EnableCommonConfig
注解中。
如果有多个需要整合的注解,一并写到 EnableCommonConfig 注解类上即可。这样,无论有多少注解,都只需在 SpringbootRegisterApplication 启动类上标注为 @EnableCommonConfig
。
7. 自动配置原理
为什么要学习自动配置原理?
① 在实际开发中,经常定义一些公共组件提供给各个团队使用。为了让使用更方便,经常将这些公共组件定义成 starter。想自定义 starter,就必须要了解自动配置原理。
② 面试经常问。
自动配置:遵循约定大约配置的原则,在 boot 程序启动后,起步依赖中的一 些 bean 对象会自动注入到 ioc 容器。
在前面章节的代码中,为了将 jar 包中的 Country 和 Province 的 bean 对象注入 IOC 容器:① 提供了 CommonConfig 配置类,这个配置类含有 country() 和 province() 方法,分别用于向 IOC 容器中注入 Country 和 Province 的 bean 对象;② 在启动类上添加 @Import 注解,将 CommonConfig 配置类导入进来。这样 Country 和 Province 的 bean 对象才能注入了 IOC 容器。
但是,该过程并没有实现 bean 的自动配置。
在 SpringBoot 整合 mybatis 时,只需要引入 mybatis 的起步依赖,之后,像 SqlSessionFactoryBean 这样的 bean 对象就自动注入到了 IOC 容器中,并没有写相应的配置。
如何才能像 SpringBoot 整合 mybatis 那样,使 bean 对象自动注入 IOC 容器呢?下面提供一种方案:
(1) CommonConfig 配置类由 jar 包来提供
(2) jar 包提供一个自动配置类,该自动配置类上有两个注解:① @AutoConfiguration
,用来标识该类是自动配置类;② @Import
,用于导入 CommonConfig 配置类
(3) jar 包提供 .imports
配置文件,并把自动配置类的全类名配置到该文件中
此时就可以通过下面的代码直接获取到 bean:
输出结果:
Province{name='null', direction='null'}
面试题:说一说 SpringBoot 自动配置原理?
- 在主启动类上添加了 SpringBootApplication 注解,这个注解组合了 EnableAutoConfiguration 注解;
- EnableAutoConfiguration 注解又组合了 Import 注解,导入了 AutoConfigurationImportSelector 类;
- AutoConfigurationImportSelector 类实现了 ImportSelector 接口,以及该接口中的 selectImports 方法。该方法经过层层调用,最终会读取 META-INF 目录下后缀名为 imorts 的文件,当然,boot 2.7 以前的版本,读取的是 spring.factories 文件(2.7之前是 factories 文件,2.7~3.0 兼容两种文件,3.0 之后只有 imports 文件);
- imorts 文件中配置了很多自动配置类的全类名,SpringBoot 读取到这些全类名之后,会解析注册条件(@Conditional 及其衍生注解),把满足注册条件的 Bean 对象自动注入到 IOC 容器中。
8. 自定义 Starter
在实际开发中,经常会定义一些公共组件,提供给各个项目团队使用。而在SpringBoot 项目中,一般会将这些公共组件封装为 starter。
这里以 mybatis 的 starter 为例来说明,一般来说,起步依赖由两个工程组成:(1) xxx-autoconfigure,提供自动配置功能;(2) xxx-starter,提供依赖管理功能。
我们会在 starter 中引入 autoconfigure,这样别人在使用的时候只要引入 starter 就可以了。当把这两个工程提供好之后,自定义的 starter 也就制作好了。
需求:自定义 mybatis 的 starter
(1) 创建 dmybatis-spring-boot-autoconfigure 模块,提供自动配置功能,并自定义配置文件 META-INF/spring/xxx.imports
① 在 autoconfigure 中添加自动配置功能,就要引入对应的依赖,但我们现在可能不是很清楚要引入什么。不过可以参考 SpringBoot 整合 mybatis 时,mybatis 的起步依赖引入了哪些坐标
除了需要自己提供的 autoconfigure,其他都要引入进来:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>3.1.5</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId><version>3.1.2</version>
</dependency>
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version>
</dependency>
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>3.0.0</version>
</dependency>
② 提供 autoconfigure 自动配置类:需要提供两个方法,分别用来注入SqlSessionFactoryBean 和MapperScannerConfigure 的 Bean 对象。
③ 提供 .imports
配置文件,并把自动配置类的全类名配置到该文件中。.imports
配置文件采用与 mybatis 中相同的文件名。
到此为止,autoconfigure 工程已经具备了自动配置的功能。
(2) 创建 dmybatis-spring-boot-starter 模块,在 starter 中引入自动配置模块
starter 模块只提供依赖管理功能,首先要引入刚刚的 autoconfigure。
除了要引入 autoconfigure 之外,autoconfigure 中引入的依赖也要再引入一下。因为将来使用的时候是直接引入 starter,如果需要对其中的依赖进行排除等操作就会更方便。这也是官方推荐的做法。
对于 autoconfigure 和 starter 中的文件,以下都是不需要的:
删除多余文件后:
至此,mybatis 起步依赖才真正完成。可以实现与官方提供的 mybatis 起步依赖相同的作用了。
一个bug,如果出现这样的错误:
maven 工程默认的 jdk 版本是5,太低了。可以在 pom.xml 中配置两个编译的插件:
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>17</source><target>17</target></configuration></plugin></plugins>
</build>
位置:
相关文章:

1. SpringBoot3 基础
文章目录 1. SpringBoot 概述2. SpringBoot 入门3. SpringBoot 配置文件3.1 SpringBoot 配置文件基本使用3.2 yml 配置文件 4. SpringBoot 整合 Mybatis5. Bean 管理5.1 Bean 扫描5.2 Bean 注册5.3 注册条件 6. 组合注解7. 自动配置原理8. 自定义 Starter 1. SpringBoot 概述 …...

美易官方:苹果承认GPU安全漏洞存在:iPhone 12和M2系列受影响
苹果承认GPU安全漏洞存在: iPhone 12和M2 MacBook Air受影响 近日,苹果公司承认其部分产品存在GPU安全漏洞,这些漏洞可能会影响iPhone 12和M2 MacBook Air等设备的安全性。这一消息引起了广泛的关注和担忧,因为这些设备是许多用户…...

【Vue3】3-1 : 章节介绍 - Vue3组件应用及单文件组件
本书目录:点击进入 一、本章学习目标 二、课程安排 一、本章学习目标 Vue3组件相关概念掌握组件之间的通信封装一个可复用的组件单文件组件SFC:即.vue文件 样式 结构 逻辑脚手架的使用和底层实现机制工程化的认知 二、课程安排 组件的概念及组件的基…...

【数据结构】二叉树(遍历,递归)
🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343🔥 系列专栏:《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm1001.2014.3001.5482 目录 二叉树遍历规则 前序遍历 …...

《微信小程序开发从入门到实战》学习八十五
6.15 设备API 6.15.2 添加联系人API 使用wx.addPhoneContact接口可以在用户的手机通讯录中添加联系人信息。用户可以选择“新增联系人”或“添加到已有联系人”。该接口接受Object参数,参支持属性如下所示: firstName:必填,名字…...

设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,它将一个请求封装为一个对象,使发出请求的对象和执行请求的对象解耦。这样可以方便地对请求排队、记录日志、撤销/重做操作以及支持可扩展性。 原理 命令接口(Comman…...

Modbus协议学习第三篇之协议通信规则
导语 本篇博客将深入介绍Modbus协议的一些内容,主要包括通讯方式和通讯模型的介绍 Modbus通讯方式 Modbus协议是单主机、多从机的通信协议,即同一时间,总线上只能有一个主设备,但可以有一个或者多个从设备(最多好像是2…...

git仓库使用说明
Git软件使用 1.先下载git相关软件 下载地址: Git - Downloading Package (git-scm.com) 下载其中一个安装 2.打开gitee网站,注册账号 3.打开个人中心,选择ssh公钥,查看如何生成公钥 4.生成公钥后,添加相应的公钥 …...

边缘计算和联邦学习的联系
1. 什么是边缘计算? 边缘计算(Edge Computing)是一种计算模型,其主要思想是将计算、存储和数据处理能力推送到离数据源近的边缘设备,而不是依赖于远程的云服务器。这样做的目的是减少数据传输延迟、提高响应速度&…...
机器学习算法理论:贝叶斯
贝叶斯定理对于机器学习来说是经典的概率模型之一,它基于先验信息和数据观测来得到目标变量的后验分布。具体来说,条件概率(也称为后验概率)描述的是事件A在另一个事件B已经发生的条件下的发生概率,公式表示为P(A|B)&a…...

229.【2023年华为OD机试真题(C卷)】手机App防沉迷系统(模拟-JavaPythonC++JS实现)
🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-手机App防沉迷系统二.解题思路三.题解代码Pyth…...

关系运算符
Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 补充: 如果要想对所选择的数据行进行控制,那么可以利用 WHERE 子句完成,此时的 SQL 语法结构变为如下形式 先系统性介绍下: ● 关系运算: >、、&…...

K8s-架构
一、K8s节点划分 K8s集群包含Master(控制节点)和Node(工作节点),应用部署在Node节点上。 集群架构图: 二、Master节点 Master节点分成四个组件:scheduler、ApiServer、Controller Manager、ETCD。类似三层结构,controller&#…...

C++ 并发编程 | 进程与线程
一、进程与线程 1、进程 1.1、定义 操作系统中最核心的概念就是进程,进程是对正在运行中的程序的一个抽象,是系统进行资源分配和调度的基本单位。进程是一种抽象的概念,一般由程序、数据集合和进程控制块三部分组成,如下&#x…...

基于Python实现身份证信息识别
目录 前言身份证信息识别的背景与意义自动识别身份证的需求实现环境与工具准备Python编程语言OpenCV图像处理库Tesseract OCR引擎身份证信息识别算法原理图像预处理步骤(图像裁剪、灰度化 、二值化、去噪)信息提取与解析Python代码实现通过OCR提取身份证号码代码解析身份证信息…...

深度学习记录--正则化(regularization)
什么是正则化? 正则化(regularization)是一种实用的减少方差(variance)的方法,也即避免过度拟合 几种正则化的方法 L2正则化 又被称为权重衰减(weight dacay) 在成本函数中加上正则项: 其中 由于在w的更新过程中会递减,即权…...

Java的便捷输入方法及解析
在 Java 中,有多种便捷的输入方法可以从用户那里获取输入。下面是一些常见的便捷输入方法及解析: 使用 Scanner 类:在上述示例中,首先导入了 java.util.Scanner 类,创建了一个 Scanner 对象,并使用 System…...

抖音矩阵云混剪系统源码(免授权版)多平台多账号一站式管理,附带系统搭建教程
搭建教程 MySQL 5.6 PHP 7.2 Apache 数据库名称 juzhen Nginx环境切换伪静态 1、解压安装包到项目根目录,找到application/database.php 更换自己的数据库密码 2、阿里云现有的配置不要动 其他按照文档进行添加 3、项目访问目录:public 4、域名…...

【Linux】权限的深度解析
前言:在此之前我们学习了一些常用的Linux指令,今天我们进一步学习Linux下权限的一些概念 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:Linux的学习 👈 💯代码仓库:卫卫周大胖的学习日记&a…...

c++函数怎么返回多个值
文章目录 使用结构体或类:定义一个结构体或类,其中包含了所有需要返回的值。然后在函数中返回这个结构体或类的实例。 struct Result {int value1;double value2;char value3; };Result myFunction() {Result r;r.value1 1;r.value2 2.0;r.value3 a;r…...

《剑指 Offer》专项突破版 - 面试题 15 : 字符串中的所有变位词(C++ 实现)
题目链接:LCR 015. 找到字符串中所有字母异位词 - 力扣(LeetCode) 题目: 输入字符串 s1 和 s2,如何找出字符串 s2 的所有变位词在字符串 s1 中的起始下标?假设两个字符串中只包含英文小写字母。例如&…...

03 SpringMVC响应数据之接收Cookie和请求头+原生API+共享域对象操作
下载postman,测试传json数据 1. 接收cookie 用CookieValue注解将cookie值绑定到控制器中的handler参数。 Controller类中的一个handler GetMapping("/CookieTest") public void handle(CookieValue("cookie的id(name)") String cookie) { //... }2. 接收…...

数据仓库(3)-模型建设
本文从以下9个内容,介绍数据参考模型建设相关内容。 1、OLTP VS OLAP OLTP:全称OnLine Transaction Processing,中文名联机事务处理系统,主要是执行基本日常的事务处理,比如数据库记录的增删查改,例如mysql、oracle…...

交换机配置及网络测试
实验环境 拓扑图 Ip规划表 部门 主机数量 网络地址 子网掩码 网关 可用ip Vlan 市场部 38 192.168.131.0 255.255.255.0 192.168.131.1 2-254 11 研发部 53 192.168.132.0 255.255.255.0 192.168.132.1 2-254 12 财务部 9 192.168.133.0 255.255.255…...

贪吃蛇游戏
文章目录 前言一.Win32API1.1GetStdHandle1.2GetConsoleCursorInfo1.3SetConsoleCursorInfo1.4SetConsoleCursorPosition1.5GetAsyncKeyState1.6setlocale二.游戏设计三.GameStart3.1蛇的创建3.2分文件3.3控制台设置3.4WelComeToGame3.5CreateMap3.6InitSnack3.7CreateFood 四.…...

DPDK trace 的简单使用
文章目录 前言trace的简单使用 前言 日志用于记录不太频繁,比较高level的事情。trace记录频繁发生的事情,它的开销低。 trace可以在运行时,通过参数控制是否启用;可以在任何时间点,将trace记录的缓冲区保存到文件系统…...

《游戏-01_2D-开发》
首先利用安装好的Unity Hub创建一个unity 2D(URP渲染管线)项目 选择个人喜欢的操作格局(这里采用2 by 3) 在Project项目管理中将双栏改为单栏模式(个人喜好) 找到首选项(Preferences)…...

如何禁用WordPress站点的管理员电子邮件验证或修改检查频率?
今天boke112百科登录某个WordPress站点时,又出现“管理员邮件确认”的提示,要求确认此站点的管理员电子邮箱地址是否仍然正确。具体如下图所示: 如果点击“稍后提醒我”,那么管理员邮件验证页面就会在3天后重新显示。 说实话&…...

三、MySQL实例初始化、设置、服务启动关闭、环境变量配置、客户端登入(一篇足以从白走到黑)
目录 1、选择安装的电脑类型、设置端口号 2、选择mysql账号密码加密规则 3、设置root账户密码 4、设置mysql服务名和服务启动策略 5、执行设置(初始化mysql实例) 6、完成设置 7、MySQL数据库服务的启动和停止 方式一:图形化方式 方式…...

Ubuntu20.04-剪贴板
针对图形界面用户 1.两种方式 1.1 安装Parcellite 简单轻量级剪贴板管理器 sudo apt install parcellite 1.2 安装Gpaste 更强大的剪贴板管理器,包含历史记录和同步功能 sudo apt install gpaste...