1. SpringBoot3 基础

这篇具有很好参考价值的文章主要介绍了1. SpringBoot3 基础。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. SpringBoot 概述

在 SpringBoot 之前,通过 Spring Framework 整合各种子项目,来构建 Spring应用程序:

1. SpringBoot3 基础,SpringBoot,java,spring boot

传统方式构建 spring 应用程序,需要挨个导入依赖,项目配置繁琐:

1. SpringBoot3 基础,SpringBoot,java,spring boot
SpringBoot 是 Spring 提供的一个子项目,用于快速构建 Spring 应用程序:

1. SpringBoot3 基础,SpringBoot,java,spring boot

SpringBoot 的特性,用于简化开发:

(1) 起步依赖:本质上就是一个 Maven 坐标,整合了完成一个功能需要的所有坐标。

1. SpringBoot3 基础,SpringBoot,java,spring boot

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

(2) 自动配置:遵循约定大约配置的原则,在 boot 程序启动后,一些 bean 对象会自动注入到 ioc 容器,不需要手动声明,简化开发。

比如现在要整合 mybatis:

  • 传统的方法,首先要整合 mybatis 依赖,还要声明两个 bean 对象。
  • 使用 SpringBoot 整合 mybatis 时,只需要引入 mybatis 起步依赖,因为起步依赖会自动引入前述的两个 bean 对象。

1. SpringBoot3 基础,SpringBoot,java,spring boot

<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~

1. SpringBoot3 基础,SpringBoot,java,spring boot
使用 SpringBoot 后,不必再像之前那样繁琐,只需以下两个步骤:
1. SpringBoot3 基础,SpringBoot,java,spring boot
下面从用 idea 创建工程开始,实现上面的需求:

(1) 创建 springboot 工程

1. SpringBoot3 基础,SpringBoot,java,spring boot

1. SpringBoot3 基础,SpringBoot,java,spring boot
1. SpringBoot3 基础,SpringBoot,java,spring boot

1. SpringBoot3 基础,SpringBoot,java,spring boot
1. SpringBoot3 基础,SpringBoot,java,spring boot

(2) 下面来看一下新创建的 SpringBoot 工程中有什么内容。

1. SpringBoot3 基础,SpringBoot,java,spring boot

pom.xml 文件中有自动导入的起步依赖:

1. SpringBoot3 基础,SpringBoot,java,spring boot

@SpringBootApplication 标识当前类是 SpringBoot 启动类,是程序的入口:

1. SpringBoot3 基础,SpringBoot,java,spring boot

资源目录:

1. SpringBoot3 基础,SpringBoot,java,spring boot

(3) 新建 controller 目录,编写 HelloController

1. SpringBoot3 基础,SpringBoot,java,spring boot

(4) 运行 main 方法
当 main 方法运行时,SpringBoot 工程就会启动,它内置的 tomcat 也会自动启动,并且把 Controller 这样的资源部署好,这样就能够通过浏览器访问了。

1. SpringBoot3 基础,SpringBoot,java,spring boot

3. SpringBoot 配置文件

3.1 SpringBoot 配置文件基本使用

SpringBoot 提供了多种属性配置方式,一种是 properties 配置文件,另一种是 yml / yaml 配置文件(yml 和 yaml 只是名字不同,没其他区别)。

首先来看 properties 配置文件,在使用 Spring Initializer 创建 SpringBoot 工程时,会自动生成application.properties 配置文件。

1. SpringBoot3 基础,SpringBoot,java,spring boot

我们可以在其中配置一些信息,且该配置文件是 SpringBoot 可以自动识别的。下面这个链接中给出了在该配置文件中可以配置的内容:
docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties

1. SpringBoot3 基础,SpringBoot,java,spring boot

可以看到,这些配置都有一些默认值。如:tomcat 启动时默认绑定 8080 端口,当前项目的虚拟目录默认没有配置。

1. SpringBoot3 基础,SpringBoot,java,spring boot

对于这些默认配置,我们可以在 application.properties 进行修改:

1. SpringBoot3 基础,SpringBoot,java,spring boot

修改后再次启动 SpringBoot 工程:

1. SpringBoot3 基础,SpringBoot,java,spring boot

在浏览器中访问:

1. SpringBoot3 基础,SpringBoot,java,spring boot

下面简单介绍 yml / yaml 配置文件(只是名字不同,没其他区别,常写作 yml)。

该配置文件与 properties 配置文件的内容相同,只是格式不同。properties 配置文件的层级关系通过 . 来体现,yml 配置文件的层级关系通过 换行和缩进 来体现。

1. SpringBoot3 基础,SpringBoot,java,spring boot
创建 yml 文件,写入配置信息:

1. SpringBoot3 基础,SpringBoot,java,spring boot

启动工程:

1. SpringBoot3 基础,SpringBoot,java,spring boot

浏览器访问:

1. SpringBoot3 基础,SpringBoot,java,spring boot

3.2 yml 配置文件

在实际开发中,yml 配置文件与 properties 配置文件相比,书写格式相对清晰,所以更常用。下面对 yml 配置文件展开详细介绍。

yml 配置文件在实际开发中有两种使用方式:

(1) 书写三方技术所需的配置信息
例如,程序中要使用 redis,要做的就是:① 引入 redis 起步依赖;② 根据 redis文档编写配置信息。起步依赖会在工程启动之后,自动获取编写的配置信息,所以无需手动获取。后续会详细介绍 SpringBoot 如何整合三方技术。
1. SpringBoot3 基础,SpringBoot,java,spring boot

(2) 书写自己程序所需的自定义配置信息(本节重点)
举个例子:在使用阿里云对象服务时,Java 代码中会有一些服务相关的配置信息:

1. SpringBoot3 基础,SpringBoot,java,spring boot

如果这样,配置信息就跟 Java 代码耦合了。一旦配置信息发生变化,就必须去修改 Java 代码,重新进行编译、测试、打包、部署等操作,十分耗时。在实际开发中,常常将配置信息书写到配置文件中。这样,当配置文件中的信息发生改变时,重启服务器即可,不需要重新编译、测试、打包、部署等操作。

当配置信息书写到配置文件中时,Java 代码想要获取这些配置信息,就要通过代码来手动获取,因为不能自动获取。

书写配置信息

下面是发送邮件的代码所用到的一个实体类,其中有一些配置信息,需要将它们抽取到 properties 或 yml 配置文件中:

1. SpringBoot3 基础,SpringBoot,java,spring boot

上面的配置文件中的键为什么要用 email 做前缀? 因为其他地方也可能有 user、code 等这种键名,加上前缀是为了防止冲突。

注意 yml 文件的书写格式:

  • 值前边必须有空格,作为分隔符
  • 缩进表示层级关系,相同的层级左侧对齐

扩展:数组配置项的书写格式

hobbies:
  - "eat"
  - "drink"
  - "play"

获取配置信息

方法 1: 在 Java 代码的成员变量上添加 @Value("${键名}")

1. SpringBoot3 基础,SpringBoot,java,spring boot

方法 2: 使用 @ConfigurationProperties(prefix="前缀") 注解,同时成员变量名与配置文件中的键名保持一致。(更简洁)

1. SpringBoot3 基础,SpringBoot,java,spring boot

4. SpringBoot 整合 Mybatis

Spring 整合 mybatis 时,需要引入 mybatis 依赖以及 mybatis 和 spring 的整合依赖,此外还需要配置一些 bean 对象,如:SqlSessionFactoryBean、MapperScannerConfigurer、Datasource。

1. SpringBoot3 基础,SpringBoot,java,spring boot

上面的过程相对繁琐,SpringBoot提供了更为简洁的方式:

(1) 引入 mybatis 起步依赖:相当于将 mybatis 依赖以及 mybatis 和 spring 的整合依赖全部引进来了。同时,该起步依赖会自动将 bean 对象注入 IOC 容器中,也就是前述的 bean 对象都无需再手动配置。

(2) 配置 yml 文件:让 mybatis 去操作数据库。

1. SpringBoot3 基础,SpringBoot,java,spring boot

接下来就可以正常地去编写 Controller、Service、Mapper。当浏览器访问 Controller 时,Controller 去访问 Service,Service 去访问 Mapper,Mapper 最终去操作数据库。
1. SpringBoot3 基础,SpringBoot,java,spring boot

案例:查询 User 表中指定 id 的数据,相应给浏览器
1. SpringBoot3 基础,SpringBoot,java,spring boot

(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 中添加依赖

1. SpringBoot3 基础,SpringBoot,java,spring boot

(3) 配置数据源信息

1. SpringBoot3 基础,SpringBoot,java,spring boot

(4) 到这里,SpringBoot 整合 mybatis 就完成了,下面开始各个类的编写。

1. SpringBoot3 基础,SpringBoot,java,spring boot

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

运行结果:

1. SpringBoot3 基础,SpringBoot,java,spring boot

5. Bean 管理

5.1 Bean 扫描

在 SpringBoot 之前,需要用以下方式来扫描 Bean:

1. SpringBoot3 基础,SpringBoot,java,spring boot
但是,使用 SpringBoot 时,两种方法都没有用到,却依然能扫描到我们写的 Controller、Service 等等,这是因为 SpringBoot 的启动类上有 @SpringBootApplication 注解,且该注解整合了 @ComponentScan 注解:

1. SpringBoot3 基础,SpringBoot,java,spring boot

需要要注意的是,该注解并没有指定要扫描的包路径,那么 Controller、Service 等是如何被扫描到的呢?

如果不指定扫描路径,默认扫描的是添加了该注解的类所在的包及其子包。

1. SpringBoot3 基础,SpringBoot,java,spring boot

在此工程中,默认扫描的包就是 springbootmybatis。如果将 Controller 移出该包,就扫描不到它了:

1. SpringBoot3 基础,SpringBoot,java,spring boot
1. SpringBoot3 基础,SpringBoot,java,spring boot

此时,如果还想要 Controller 被扫描到,就要在启动类上添加 @ConponentScan 注解,指明要扫描的包:

1. SpringBoot3 基础,SpringBoot,java,spring boot

5.2 Bean 注册

Bean 注册:把 Bean 对象注册到 IOC 容器中。

可以在类上添加下面的注解,从而把该类的对象注册到 IOC 容器中:

1. SpringBoot3 基础,SpringBoot,java,spring boot

@Controller@Service@Repository 的地方也可以用 @Component,只是用这三个注解能够增强可读性。

但是针对三方的类(不是自定义的),就不能再使用这些注解将其 Bean 对象注入到 IOC 容器。那该怎么办呢?Spring 提供了 @Bean@Import 两个注解来解决这个问题。

在使用这两个注解之前,首先要做一些准备工作:

pom.xml 文件:并没有引入 web 起步依赖,而是引入了 SpringBoot 核心依赖。因为在本节不做 web 的开发,只是注册 bean 对象。用 web 起步依赖的话,每次都要启动 tomcat,比较麻烦。

1. SpringBoot3 基础,SpringBoot,java,spring boot

在 pom.xml 中导入一个三方 jar 包

1. SpringBoot3 基础,SpringBoot,java,spring boot

我们的目标是将该 jar 包中的 Country 和 Province 的 bean 对象注入到 IOC 容器中。

(1) 用 @Bean 将三方 bean 对象注入 IOC 容器

@Bean 将第三方 bean 对象注入到 IOC 容器,可以通过在启动类中声明一个方法来实现。该方法有 @Bean 注解,并返回一个创建好的对象。当 Spring 解析到该方法时,就会将该方法的返回值自动注入 IOC 容器。

1. SpringBoot3 基础,SpringBoot,java,spring boot

如果能将上面的 bean 对象从 IOC 容器中拿出来,就能够验证操作有效。

验证方法:启动类中的 SpringApplication.run() 方法用于启动工程,同时也会返回 Spring 初始化好的容器,所以可以通过该方法接收到 IOC 容器,进而拿到刚刚放入的 bean 对象。

1. SpringBoot3 基础,SpringBoot,java,spring boot

输出结果:

Country{name='null', system='null'}

但是,启动类中写其他的功能不是一种好的编程习惯,所以以这种方式将三方 bean 注入 IOC 容器不推荐

如果要注册第三方的 bean,建议在配置类(用@Configuration 标识)中集中注册。

具体就是,在配置类中声明与启动类中相同的方法(带 @Bean 注解)就能将该方法的返回值注入到 IOC 容器中了。需要注意的是,该配置类需要放到启动类所在的包或其子包下(为了能被扫描到)。

1. SpringBoot3 基础,SpringBoot,java,spring boot

如果想要在 IOC 中注入多个三方 bean 对象,声明类似的方法即可。

1. SpringBoot3 基础,SpringBoot,java,spring boot

还是用与前面形同的方法进行验证:

1. SpringBoot3 基础,SpringBoot,java,spring boot

输出结果:

Country{name='null', system='null'}
Province{name='null', direction='null'}

在启动类中获取已经注入 IOC 容器中的 bean 对象时,也可以通过 bean 对象的名称来获取。bean 对象的默认名称是将其注入到 IOC 容器的方法的名称。

System.out.println(context.getBean("province"));

当然,bean 对象的名称也可以指定:

1. SpringBoot3 基础,SpringBoot,java,spring boot

此时,启动类中,根据名称获取 bean 对象的操作应为:

System.out.println(context.getBean("aa"));

如果方法内部需要使用 IOC 容器中已经存在的 bean 对象,只需在方法上声明即可,Spring 会自动注入:

1. SpringBoot3 基础,SpringBoot,java,spring boot

输出结果:

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 容器中。(相当于手动扫描)

1. SpringBoot3 基础,SpringBoot,java,spring boot

xxx 类可以是一个普通类,也可以是一个配置类。在实际开发中,通常是配置类或 ImportSelector 接口的实现类。

为了演示 @Import 的作用,首先将 Controller 移出启动类的扫描范围:

1. SpringBoot3 基础,SpringBoot,java,spring boot

CommonConfig.java:

1. SpringBoot3 基础,SpringBoot,java,spring boot

① Import 配置类

1. SpringBoot3 基础,SpringBoot,java,spring boot

如果有多个这样的配置类,可以把多个配置类放到一个数组中:

@Import({CommonConfig1.class, CommonConfig2.class, CommonConfig3.class})

但是,如果类似的配置文件过多,就会使这段代码很臃肿。此时,可以使用 ImportSelector 接口的实现类来解决。

② Import ImportSelector 接口的实现类

首先要定义一个类去实现 ImportSelector 接口,并重写其中的 selectImports() 方法。

1. SpringBoot3 基础,SpringBoot,java,spring boot

selectImports() 方法返回一个字符串数组,每个元素就是要注入到 IOC 容器中的 bean 对象全类名。

需要注意的是,SpringBoot 会自动调用 selectImports() 方法,得到含全类名的数组,并把这些类的 bean 对象注入到 IOC 容器中。

1. SpringBoot3 基础,SpringBoot,java,spring boot

此时,就不再 Import 配置类了,而是 ImportSelector 接口的实现类:

1. SpringBoot3 基础,SpringBoot,java,spring boot

这样,工程启动之后,就会扫描到 @Import 注解,再去找到 CommonImportSelector 这个实现类,自动执行 selectImports() 方法,得到 bean 对象的全类名,并将对应的 bean 对象注入到 IOC 容器中。

在实际开发中,selectImports() 方法中的全类名数组并不是写死的,而是从配置文件中获取到的。这样的话,有哪些 bean 对象需要注入,就只需要将其对应的全类名写在配置文件里。下面介绍具体操作:

首先,新建 common.imports 文件,写入 bean 对象对应的全类名(如果有多个,就写多行):

1. SpringBoot3 基础,SpringBoot,java,spring boot

然后,在 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 代码,从而需要重新编译等工作。

规范的写法是:将这些值写到配置文件中:

1. SpringBoot3 基础,SpringBoot,java,spring boot

再用 @Value 注解将配置文件中的值注入到 java 代码的相应变量中
【注】@Value 不仅可以添加到成员变量上,也可以添加到参数列表上

1. SpringBoot3 基础,SpringBoot,java,spring boot

此时如果将配置文件中的内容全部注释掉,代码就会因无法解析变量而报错。如果我们想要:配置文件里有值,就注入变量;没有值,就不注入。该怎么办呢?

要达到这种效果,需要用到注册条件相关知识。

SpringBoot 提供了设置注册生效条件的注解 @Conditional,可以借助该注解设置 Bean 注册的条件。但是该注解的使用较为繁琐,SpringBoot 提供了其衍生注解:

1. SpringBoot3 基础,SpringBoot,java,spring boot

(1) @ConditionalOnProperty 注解:配置文件中存在对应的属性,才将该 bean 注入 IOC 容器

1. SpringBoot3 基础,SpringBoot,java,spring boot

(2) @ConditionalOnMissingBean 注解:当不存在某类型的 bean 时,才将该 bean 注入 IOC 容器

1. SpringBoot3 基础,SpringBoot,java,spring boot

(3) @ConditionalOnClass 注解:当前环境存在某个类时,才将该 bean 注入 IOC 容器

1. SpringBoot3 基础,SpringBoot,java,spring boot

获取 DispatcherServlet 类的全类名的方式:按两下 Shift ➡ 输入类名 DispatcherServlet ➡ 选择 Classes ➡ 进入类。

1. SpringBoot3 基础,SpringBoot,java,spring boot

在类名上右键,Copy ➡ Copy Reference

1. SpringBoot3 基础,SpringBoot,java,spring boot

可以看到,当前的工程没有引入 web 起步依赖:

1. SpringBoot3 基础,SpringBoot,java,spring boot

所以就不能在 IOC 容器中获取到 Province 的 bean 对象,只有添加了 web 起步依赖,当前环境才会有 DispatcherServlet 类,进而向 IOC 容器注入 Province 的 bean 对象。

以上三个注解,经常会在自定义 starter 或 SpringBoot 源码中看到。

6. 组合注解

定义一个注解类

1. SpringBoot3 基础,SpringBoot,java,spring boot

1. SpringBoot3 基础,SpringBoot,java,spring boot

这样就能把 @Import(CommonImportSelector.class) 注解整合到 @EnableCommonConfig 注解中。

1. SpringBoot3 基础,SpringBoot,java,spring boot

如果有多个需要整合的注解,一并写到 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 容器。

1. SpringBoot3 基础,SpringBoot,java,spring boot

但是,该过程并没有实现 bean 的自动配置。

在 SpringBoot 整合 mybatis 时,只需要引入 mybatis 的起步依赖,之后,像 SqlSessionFactoryBean 这样的 bean 对象就自动注入到了 IOC 容器中,并没有写相应的配置。

如何才能像 SpringBoot 整合 mybatis 那样,使 bean 对象自动注入 IOC 容器呢?下面提供一种方案:

(1) CommonConfig 配置类由 jar 包来提供
(2) jar 包提供一个自动配置类,该自动配置类上有两个注解:① @AutoConfiguration,用来标识该类是自动配置类;② @Import,用于导入 CommonConfig 配置类
(3) jar 包提供 .imports 配置文件,并把自动配置类的全类名配置到该文件中

1. SpringBoot3 基础,SpringBoot,java,spring boot

此时就可以通过下面的代码直接获取到 bean:

1. SpringBoot3 基础,SpringBoot,java,spring boot

输出结果:

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,提供依赖管理功能。

1. SpringBoot3 基础,SpringBoot,java,spring boot
我们会在 starter 中引入 autoconfigure,这样别人在使用的时候只要引入 starter 就可以了。当把这两个工程提供好之后,自定义的 starter 也就制作好了。

需求:自定义 mybatis 的 starter

(1) 创建 dmybatis-spring-boot-autoconfigure 模块,提供自动配置功能,并自定义配置文件 META-INF/spring/xxx.imports

1. SpringBoot3 基础,SpringBoot,java,spring boot

① 在 autoconfigure 中添加自动配置功能,就要引入对应的依赖,但我们现在可能不是很清楚要引入什么。不过可以参考 SpringBoot 整合 mybatis 时,mybatis 的起步依赖引入了哪些坐标

1. SpringBoot3 基础,SpringBoot,java,spring boot

除了需要自己提供的 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 对象。

1. SpringBoot3 基础,SpringBoot,java,spring boot

③ 提供 .imports 配置文件,并把自动配置类的全类名配置到该文件中。.imports 配置文件采用与 mybatis 中相同的文件名。

1. SpringBoot3 基础,SpringBoot,java,spring boot
1. SpringBoot3 基础,SpringBoot,java,spring boot
到此为止,autoconfigure 工程已经具备了自动配置的功能。

(2) 创建 dmybatis-spring-boot-starter 模块,在 starter 中引入自动配置模块

starter 模块只提供依赖管理功能,首先要引入刚刚的 autoconfigure。

除了要引入 autoconfigure 之外,autoconfigure 中引入的依赖也要再引入一下。因为将来使用的时候是直接引入 starter,如果需要对其中的依赖进行排除等操作就会更方便。这也是官方推荐的做法。

1. SpringBoot3 基础,SpringBoot,java,spring boot

对于 autoconfigure 和 starter 中的文件,以下都是不需要的:

1. SpringBoot3 基础,SpringBoot,java,spring boot

删除多余文件后:

1. SpringBoot3 基础,SpringBoot,java,spring boot

至此,mybatis 起步依赖才真正完成。可以实现与官方提供的 mybatis 起步依赖相同的作用了。

1. SpringBoot3 基础,SpringBoot,java,spring boot

一个bug,如果出现这样的错误:

1. SpringBoot3 基础,SpringBoot,java,spring boot

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 基础,SpringBoot,java,spring boot文章来源地址https://www.toymoban.com/news/detail-807889.html

到了这里,关于1. SpringBoot3 基础的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 1. SpringBoot3 基础

    在 SpringBoot 之前,通过 Spring Framework 整合各种子项目,来构建 Spring应用程序: 传统方式构建 spring 应用程序,需要挨个导入依赖,项目配置繁琐: SpringBoot 是 Spring 提供的一个子项目,用于快速构建 Spring 应用程序: SpringBoot 的特性,用于简化开发: (1) 起步依赖 :本质上就

    2024年01月20日
    浏览(30)
  • SpringBoot3基础用法

    目录 一、背景 二、环境搭建 1、工程结构 2、框架依赖 3、环境配置 三、入门案例 1、测试接口 2、全局异常 3、日志打印 3.1 日志配置 3.2 日志打印 四、打包运行 五、参考源码 技术和工具「!喜新厌旧」 最近在一个轻量级的服务中,尝试了最新的技术和工具选型; 即 SpringB

    2024年02月14日
    浏览(43)
  • 【SpringBoot3】从重构HelloWorld看Spring的作用

    在我们学习一门新技术的时候,总是先运行出一个基本的程序来输出“Hello World”,如果成功了, 说明我们的开发环境基本就绪了,我们也像婴儿走路一样,能走第一步了。接下来我们就逐步改造一个最基本的HelloWorld来一步步分析Spring到底帮助我们做 了什么。 目录 第一步:

    2024年02月19日
    浏览(38)
  • 【Spring Cloud Gateway】⑥SpringBoot3.x集成SpringDoc指南

    Spring Cloud Gateway 使用 Netty 作为嵌入式服务器,并基于响应式 Spring WebFlux 。做为微服务网关,多个微服务把 API 挂在 Gateway 上,如果查看某个 API 的 Swagger 还要去各个子微服务中去查看,就很不方便,如果能在 Gateway 上直接查看各个微服务的 API 文档,会方便很多,本文以截至

    2024年02月14日
    浏览(44)
  • Java --- springboot3整合SSM

    目录 一、整合SSM场景 二、自动配置原理   引入pom依赖 数据库表: 配置数据源 配置mybatis相关配置 实体类: mapper接口: mapper接口映射文件: service实现类: controller层: 在springboot启动类添加注解: jdbc场景的自动配置 :   1、 mybatis-spring-boot-starter 导入 spring-boot-starter-jd

    2024年02月08日
    浏览(69)
  • Java21 + SpringBoot3集成WebSocket

    近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。 本项目为前后端分离开发,后端基于 Java21 和 SpringBoot3 开发,前端提供了vue、angular、react、uniap

    2024年01月23日
    浏览(54)
  • 【Spring实战项目】SpringBoot3整合WebSocket+拦截器实现登录验证!从原理到实战

    🎉🎉 欢迎光临,终于等到你啦 🎉🎉 🏅我是 苏泽 ,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏 《Spring 狂野之旅:从入门到入魔》 🚀 本专栏带你从Spring入门到入魔   这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://suzee.blog.

    2024年04月17日
    浏览(55)
  • spring-security-oauth2-authorization-server(一)SpringBoot3.1.3整合

    因为SpringBoot3.x是目前最新的版本,整合spring-security-oauth2-authorization-server的资料很少,所以产生了这篇文章,主要为想尝试SpringBoot高版本,想整合最新的spring-security-oauth2-authorization-server的初学者,旨在为大家提供一个简单上手的参考,如果哪里写得不对或可以优化的还请大家

    2024年02月03日
    浏览(42)
  • Java --- springboot3依赖管理和自动配置机制

    目录 一、依赖管理机制 二、自动配置机制  三、自动配置流程 🚕 、为什么导入 starter-web 所有相关依赖都导入进来? ①、开发什么场景,导入什么 场景启动器。 ②、maven依赖传递原则。A-B-C: A就拥有B和C ③、导入 场景启动器。 场景启动器 自动把这个场景的所有核心依赖

    2024年02月07日
    浏览(53)
  • 【SpringBoot3】--03.数据访问、基础特性(外部化和内部外配置、整合JUnit)

    学习视频: 尚硅谷SpringBoot3视频 SpringBoot 整合 Spring 、 SpringMVC 、 MyBatis 进行 数据访问场景 开发 勾选之后会导入以下包 安装 MyBatisX 插件,帮我们生成Mapper接口的xml文件即可 在接口处 : Alt + 回车 必须把mapper的xml文件映射位置在配置文件定义! 而驼峰命名转换建议也开启 编

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包