C语言中文网SpringBoot学习笔记

SpringBoot是什么

为了简化 Spring 应用的搭建和开发过程,Pivotal 团队在 Spring 基础上提供了一套全新的开源的框架,它就是 Spring Boot

Spring Boot 具有 Spring 一切优秀特性,Spring 能做的事,Spring Boot 都可以做,而且使用更加简单,功能更加丰富,性能更加稳定而健壮。

Spring Boot 提供了大量开箱即用(out-of-the-box)的依赖模块,例如 spring-boot-starter-redis、spring-boot-starter-data-mongodb 和 spring-boot-starter-data-elasticsearch 等。这些依赖模块为 Spring Boot 应用提供了大量的自动配置,使得 Spring Boot 应用只需要非常少量的配置甚至零配置,便可以运行起来,让开发人员从 Spring 的“配置地狱”中解放出来,有更多的精力专注于业务逻辑的开发。

Spring Boot 的特点

Spring Boot 具有以下特点:

1. 独立运行的 Spring 项目

Spring Boot 可以以 jar 包的形式独立运行,Spring Boot 项目只需通过命令“ java–jar xx.jar” 即可运行。

2. 内嵌 Servlet 容器

Spring Boot 使用嵌入式的 Servlet 容器(例如 Tomcat、Jetty 或者 Undertow 等),应用无需打成 WAR 包 。

3. 提供 starter 简化 Maven 配置

Spring Boot 提供了一系列的“starter”项目对象模型(POMS)来简化 Maven 配置。

4. 提供了大量的自动配置

Spring Boot 提供了大量的默认自动配置,来简化项目的开发,开发人员也通过配置文件修改默认配置。

5. 自带应用监控

Spring Boot 可以对正在运行的项目提供监控。

6. 无代码生成和 xml 配置

Spring Boot 不需要任何 xml 配置即可实现 Spring 的所有配置。

starter

Spring Boot 将日常企业应用研发中的各种场景都抽取出来,做成一个个的 starter(启动器),starter 中整合了该场景下各种可能用到的依赖,用户只需要在 Maven 中引入 starter 依赖,SpringBoot 就能自动扫描到要加载的信息并启动相应的默认配置

并不是所有的 starter 都是由 Spring Boot 官方提供的,也有部分 starter 是第三方技术厂商提供的,例如 druid-spring-boot-starter 和 mybatis-spring-boot-starter 等等。当然也存在个别第三方技术,Spring Boot 官方没提供 starter,第三方技术厂商也没有提供 starter。

以 spring-boot-starter-web 为例,它能够为提供 Web 开发场景所需要的几乎所有依赖,因此在使用 Spring Boot 开发 Web 项目时,只需要引入该 Starter 即可,而不需要额外导入 Web 服务器和其他的 Web 依赖。

spring-boot-starter-parent

在以上 pom.xml 的配置中,引入依赖 spring-boot-starter-web 时,并没有指明其版本(version),但在依赖树中,我们却看到所有的依赖都具有版本信息,那么这些版本信息是在哪里控制的呢?其实,这些版本信息是由 spring-boot-starter-parent(版本仲裁中心) 统一控制的。

spring-boot-starter-parent 是所有 Spring Boot 项目的父级依赖,它被称为 Spring Boot 的版本仲裁中心,可以对项目内的部分常用依赖进行统一管理。

查看 spring-boot-starter- parent 的底层代码,可以发现其有一个父级依赖 spring-boot-dependencies

spring-boot-dependencies 通过 dependencyManagement 、pluginManagement 和 properties 等元素对一些常用技术框架的依赖或插件进行了统一版本管理,例如 Activemq、Spring、Tomcat 等。

  • dependencyManagement :负责管理依赖;
  • pluginManagement:负责管理插件;
  • properties:负责定义依赖或插件的版本号。

YAML教程(快速入门版)

用户也可以根据自身的需要使用配置文件修改 Spring Boot 的默认设置。

SpringBoot 默认使用以下 2 种全局的配置文件,其文件名是固定的。

  • application.properties
  • application.yml

其中,application.yml 是一种使用 YAML 语言编写的文件,它与 application.properties 一样,可以在 Spring Boot 启动时被自动读取,修改 Spring Boot 自动配置的默认值。

YAML 全称 YAML Ain’t Markup Language,它是一种以数据为中心的标记语言,比 XML 和 JSON 更适合作为配置文件。

想要使用 YAML 作为属性配置文件(以 .yml 或 .yaml 结尾),需要将 SnakeYAML 库添加到 classpath 下,Spring Boot 中的 spring-boot-starter-web 或 spring-boot-starter 都对 SnakeYAML 库做了集成, 只要项目中引用了这两个 Starter 中的任何一个,Spring Boot 会自动添加 SnakeYAML 库到 classpath 下。

YAML 的语法如下:

  • 使用缩进表示层级关系。
  • 缩进时不允许使用 Tab 键,只允许使用空格。
  • 缩进的空格数不重要,但同级元素必须左侧对齐。
  • 大小写敏感。

YAML 支持以下三种数据结构:

  • 对象:键值对的集合
  • 数组:一组按次序排列的值
  • 字面量:单个的、不可拆分的值

在 YAML 中,使用“key:[空格]value**”**的形式表示一对键值对(空格不能省略)

字面量是指单个的,不可拆分的值,例如:数字、字符串、布尔值、以及日期等。

字面量直接写在键值对的“value**”**中即可,且默认情况下字符串是不需要使用单引号或双引号的。

若字符串使用双引号,则不会转义特殊字符,特殊字符会输出为其本身想表达的含义,如name: zhangsan \n lisi,输出

zhangsan 

lisi

YAML 为对象提供了 2 种写法:

  • 普通写法,使用缩进表示对象与属性的层级关系

    website: 
      name: bianchengbang
      url: www.biancheng.net
    
  • 行内写法

    website: {name: bianchengbang,url: www.biancheng.net}
    

YMAL为数组也提供了两种写法:

  • 普通写法,使用“-”表示数组中的元素

    pets:
      -dog
      -cat
      -pig
    
  • 行内写法

    pets: [dog,cat,pig]
    

以上三种数据结构可以任意组合使用,以实现不同的用户需求

YAML 组织结构:一个 YAML 文件可以由一个或多个文档组成,文档之间使用“—**”作为分隔符,且个文档相互独立,互不干扰。如果 YAML 文件只包含一个文档,则“—”**分隔符可以省略。

---
website:
  name: bianchengbang
  url: www.biancheng.net
---
website: {name: bianchengbang,url: www.biancheng.net}

pets:
  -dog
  -cat
  -pig

---
pets: [dog,cat,pig]

name: "zhangsan \n lisi"

---
name: 'zhangsan \n lisi'

Spring Boot配置绑定

“配置绑定”就是把配置文件中的值与 JavaBean 中对应的属性进行绑定

配置信息(例如,数据库配置)放在配置文件中,然后通过 Java 代码去读取该配置文件,并且把配置文件中指定的配置封装到 JavaBean(实体类) 中

SpringBoot 提供了以下 2 种方式进行配置绑定:

  • 使用 @ConfigurationProperties 注解
  • 使用 @Value 注解

注意:

  • 只有在容器中的组件,才会拥有 SpringBoot 提供的强大功能。如果我们想要使用 @ConfigurationProperties 注解进行配置绑定,那么首先就要保证该对 JavaBean 对象在 IoC 容器中,所以需要用到 @Component 注解来添加组件到容器中。
  • JavaBean 上使用了注解 @ConfigurationProperties(prefix = “person”) ,它表示将这个 JavaBean 中的所有属性与配置文件中以“person”为前缀的配置进行绑定。

示例1( @ConfigurationProperties 注解):

配置文件(yaml):

person:
  lastName: 张三
  age: 18
  boss: false
  birth: 1990/12/12
  maps: { k1: v1,k2: 12 }
  lists:
   - lisi
   - zhaoliu
  dog:
    name: 迪迪
    age: 5

实体类:

package net.biancheng.www.bean;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
* 将配置文件中配置的每一个属性的值,映射到这个组件中
*
* @ConfigurationProperties:告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定;
* prefix = "person":配置文件中哪个下面的所有属性进行一一映射
*
* 只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能;
*/
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public void setBoss(Boolean boss) {
        this.boss = boss;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }
    public void setLists(List<Object> lists) {
        this.lists = lists;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    
    @Override
    public String toString() {
        return "Person{" +
                "lastName='" + lastName + '\'' +
                ", age=" + age +
                ", boss=" + boss +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
    }
}
package springboot_create.bean;

/**
 * @Description TODO
 * @Auther SongBaoRu
 * @Date 2023/1/9 11:08
 */
public class Dog {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

controller:

@RestController
public class TestController {
    @Autowired
    Person person;

    // http://localhost:8080/hello
    @RequestMapping(value = "/hello")
    public String hello() {
        return "HELLO WORLD";
    }
    @RequestMapping(value = "person")
    public String person() {
        // http://localhost:8080/person
        return person.toString();
    }
}

访问输出:

Person{lastName=‘张三’, age=18, boss=false, birth=Wed Dec 12 00:00:00 CST 1990, maps={k1=v1, k2=12}, lists=[lisi, zhaoliu], dog=Dog{name=‘迪迪’, age=‘5’}}

示例2( @Value 注解):

只需要将Person实体类改为:

package net.biancheng.www.bean;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    @Value("${person.lastName}")
    private String lastName;
    @Value("${person.age}")
    private Integer age;
    @Value("${person.boss}")
    private Boolean boss;
    @Value("${person.birth}")
    private Date birth;
    
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public void setBoss(Boolean boss) {
        this.boss = boss;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }
    public void setLists(List<Object> lists) {
        this.lists = lists;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    
    @Override
    public String toString() {
        return "Person{" +
                "lastName='" + lastName + '\'' +
                ", age=" + age +
                ", boss=" + boss +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
    }
}

访问输出:

Person{lastName=‘张三’, age=18, boss=false, birth=Wed Dec 12 00:00:00 CST 1990, maps=null, lists=null, dog=null}

@Value 与 @ConfigurationProperties 对比

1. 使用位置不同
  • @ConfigurationProperties:标注在 JavaBean 的类名上;
  • @Value:标注在 JavaBean 的属性上。
2. 功能不同
  • @ConfigurationProperties:用于批量绑定配置文件中的配置;
  • @Value:只能一个一个的指定需要绑定的配置。
3. 松散绑定支持不同

@ConfigurationProperties:支持松散绑定(松散语法),例如实体类 Person 中有一个属性为 firstName,那么配置文件中的属性名支持以下写法:

  • person.firstName
  • person.first-name
  • person.first_name
  • PERSON_FIRST_NAME

@Vaule:不支持松散绑定。

4. SpEL 支持不同
  • @ConfigurationProperties:不支持 SpEL 表达式;
  • @Value:支持 SpEL 表达式。
5. 复杂类型封装
  • @ConfigurationProperties:支持所有类型数据的封装,例如 Map、List、Set、以及对象等;
  • @Value:只支持基本数据类型的封装,例如字符串、布尔值、整数等类型。
6. 应用场景不同

@Value 和 @ConfigurationProperties 两个注解之间,并没有明显的优劣之分,它们只是适合的应用场景不同而已。

  • 若只是获取配置文件中的某项值,则推荐使用 @Value 注解;
  • 若专门编写了一个 JavaBean 来和配置文件进行映射,则建议使用 @ConfigurationProperties 注解。

@PropertySource

如果将所有的配置都集中到 application.properties 或 application.yml 中,那么这个配置文件会十分的臃肿且难以维护,因此我们通常会将与 Spring Boot 无关的配置(例如自定义配置)提取出来,写在一个单独的配置文件中,并在对应的 JavaBean 上使用

示例(@PropertySource 注解的使用):

person 相关的自定义配置移动到 src/main/resources 下的 person.properties 中注意,必须把 application.properties 或 application.yml 中的相关配置删除),person.properties 的配置如下:

person.last-name=李四
person.age=12
person.birth=2000/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=dog
person.dog.age=2

在 Person 使用 @PropertySource 注解指向 person.properties:

package net.biancheng.www.bean;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@PropertySource(value="classpath:person.properties") //指向对应的配置文件
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public void setBoss(Boolean boss) {
        this.boss = boss;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }
    public void setLists(List<Object> lists) {
        this.lists = lists;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    
    @Override
    public String toString() {
        return "Person{" +
                "lastName='" + lastName + '\'' +
                ", age=" + age +
                ", boss=" + boss +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", dog=" + dog +
                '}';
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值