1. SpringBoot3 基础

news2024/11/23 21:21:10

文章目录

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

    @Override
    public 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;

    @Override
    public 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 {
    @Override
    public 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>

位置:
在这里插入图片描述

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

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

相关文章

蓝桥杯(C++ 矩形总面积 错误票据 分糖果1 三国游戏 分糖果2)

目录 一、矩形总面积 思路&#xff1a; 代码&#xff1a; 二、错误票据 思路&#xff1a; 代码&#xff1a; 三、分糖果1 思路&#xff1a; 代码&#xff1a; 四、三国游戏 思路&#xff1a; 代码&#xff1a; 五、分糖果2 思路&#xff1a; 代码&#xff1a;…

LLM:Sinusoidal位置编码

1&#xff1a;什么是大模型的外推性&#xff1f; 外推性是指大模型在训练时和预测时的输入长度不一致&#xff0c;导致模型的泛化能力下降的问题。例如&#xff0c;如果一个模型在训练时只使用了512个 token 的文本&#xff0c;那么在预测时如果输入超过512个 token&#xff0…

「云渲染科普」效果图渲染吃显卡还是cpu

准确来说看渲染器属于CPU渲染、还是显卡渲染。通常情况下&#xff0c;不少的渲染工作为了追求渲染效果的和速度&#xff0c;同时利用 CPU 和 GPU 的计算资源&#xff0c;达到最佳的效果图呈现方式。 一、效果图显卡渲染与cpu渲染对比 1、CPU(中央处理器)&#xff1a; - 传统的…

【数学建模美赛M奖速成系列】数据可视化方法(一)

数据可视化方法 写在前面山脊图优点缺点实现matlabpython 气泡矩阵图实现matlabpython 后续 写在前面 最近开始更新一个新的系列科研绘图&#xff0c;在同一个竞赛下&#xff0c;大家都近乎相同的解题思路下。之所以能出现一等二等三等奖的区别很大部分都在于结果的可视化&…

【总结】Linux命令中文帮助手册

1. 为什么要总结Linux命令中文帮助手册 Linux 官方并不提供中文的 help、man 帮助手册。网络上已有的前人翻译过的中文手册版本比较老&#xff0c;且翻译存在误差。从记忆角度来看&#xff0c;Linux 很多命令都不一定记得住详细的用法&#xff0c;易遗忘&#xff0c;缺少经验总…

计算机系统基础知识揭秘:硬件、处理器和校验码

计算机系统基础知识揭秘&#xff1a;硬件、处理器和校验码 一、计算机系统基础知识的重要性二、计算机系统硬件2.1、内存和存储设备2.2、输入输出设备 三、中央处理器&#xff08;CPU&#xff09;3.1、运算器3.2、控制器3.3、寄存器组3.4、多核CPU 四、数据表示4.1、原码、反码…

一文极速了解【自注意力机制】

当下如火如荼的大模型&#xff0c;其中的关键技术就是注意力机制&#xff08;Attention&#xff09;&#xff0c;于2015年提出。2017年的“Attention is all you need”一文提出了Transformer模型&#xff0c;去掉RNN&#xff0c;只保留注意力&#xff0c;性能吊打所有机器翻译…

Android Studi安卓读写NDEF智能海报源码

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?id615391857885&spma1z10.5-c.w4002-21818769070.11.1f60789ey1EsPH <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmln…

Intel杀回车载计算领域,极氪首发其第一代AI SoC

作者 |德新 编辑 |王博 Intel低调地重新杀回车载计算领域。 在两个月前&#xff0c;在上海举办的进博会上&#xff0c;Intel对外展示了基于新一代酷睿核心打造的智能座舱平台。 在此之前&#xff0c;这家芯片巨头任命了服役公司20多年的老将Jack Weast作为汽车业务的全球负责…

Zookeeper启动报错常见问题以及常用zk命令

Zk常规启动的命令如下 sh bin/zkServer.sh start 启动过程如果存在失败&#xff0c;是没办法直接看出什么问题&#xff0c;只会报出来 Starting zookeeper … FAILED TO START 可以用如下命令启动&#xff0c;便于查看zk启动过程中的详细错误 sh bin/zkServer.sh start-for…

深度学习中Numpy的一些注意点(多维数组;数据类型转换、数组扁平化、np.where()、np.argmax()、图像拼接、生成同shape的图片)

文章目录 1多维数组压缩维度扩充维度 2numpy类型转换深度学习常见的float32类型。 3数组扁平化4np.where()的用法5np.argmax()6图像拼接7生成同shape的图片&#xff0c;指定数据类型 1多维数组 a.shape(3,2);既数组h3&#xff0c;w2 a.shape(2,3,2);这里第一个2表示axis0维度上…

《30天自制操作系统》学习笔记(七)

先体验一下编译仿真方法&#xff1a; 30天自制操作系统光盘代码在下面链接&#xff0c;但是没有编译仿真工具&#xff1a; https://gitee.com/zhanfei3000/30dayMakeOS 仿真工具在下面链接&#xff1a; https://gitee.com/909854136/nask-code-ide 这是一个集成的编译仿真工…

综述:自动驾驶中的 4D 毫米波雷达

论文链接&#xff1a;《4D Millimeter-Wave Radar in Autonomous Driving: A Survey》 摘要 4D 毫米波 (mmWave) 雷达能够测量目标的距离、方位角、仰角和速度&#xff0c;引起了自动驾驶领域的极大兴趣。这归因于其在极端环境下的稳健性以及出色的速度和高度测量能力。 然而…

Xshell无法ssh连接虚拟机问题或主机无法ping通虚拟机。

常见报错如下&#xff1a; 1&#xff0c;Could not connect to ‘&#xff1f;&#xff1f;&#xff1f;’ (port 22): Connection failed. 2&#xff0c;卡在To escape to local shell, press ‘CtrlAlt]’. 3&#xff0c;Connection closing…Socket close. Connection clos…

Apache安全及优化

配置第一台虚拟机 VM1网卡 yum仓库 挂载磁盘 上传3个软件包到/目录 到/目录下进行解压缩 tar xf apr-1.6.2.tar.gz tar xf apr-util-1.6.0.tar.gz tar -xjf httpd-2.4.29.tar.bz2 mv apr-1.6.2 httpd-2.4.29/srclib/apr mv apr-util-1.6…

jetson-inference入门

jetson-inference 文章目录 jetson-inference前言一、jetson-inference二、 下载传输三、 docker的安装使用总结 前言 jetson 部署相关内容 一、jetson-inference 官方推出的体验套餐&#xff0c;提供了三种最常见的AI应用与计算机视觉的类型 图像辨识&#xff08;Image Rec…

纯CSS3的单选框、复选框、开关按钮UI库-自由分享jQuery、html5、css3的插件库

纯CSS3的单选框、复选框、开关按钮UI库-自由分享jQuery、html5、css3的插件库-遇见你与你分享

陪玩系统:最新商业版游戏陪玩语音聊天系统3.0商业升级独立版本源码

首发价值29800元的最新商业版游戏陪玩语音聊天系统3.0商业升级独立版本源码 &#xff08;价值29800&#xff09;最新陪玩3.0独立版本 &#xff0c;文件截图 结尾将会附上此系统源码以及详细搭建教程包含素材图仅用于学习使用 陪玩系统3.0独立升级版正式发布&#xff0c;此版本…

Elasticsearch各种高级文档操作2

本文来记录下Elasticsearch各种文档操作 文章目录 初始化文档数据 初始化文档数据 在进行各种文档操作之前&#xff0c;我们先进行初始化文档数据的工作

Pixels:重新定义游戏体验的区块链农场游戏

数据源&#xff1a;Pixels Dashboard 作者&#xff1a;lesleyfootprint.network 最近&#xff0c;Pixels 通过从 Polygon 转移到 Sky Mavis 旗下的 Ronin 网络&#xff0c;完成了一次战略性的转变。 Pixels 每日交易量 Pixels 在 Ronin 网络上的受欢迎程度急剧上升&#xf…