SpringBoot 基础

案例需求∶请求Controller中的方法,并将返回值响应到页面

  • 使用Spring Initilzr方式构建 Spring Boot 项目
    本质上说,Spring Initalizr是一个Web应用,它提供了一个基本的项目结构,能够帮助我们快速构建-个基础的Spring Boot项目

    Project SDK"用于设置创建项目使用的JDK版本,这里,使用之前初始化设置好的JDK版本即可;在"Choose Initializr Service URL(选择初始化服务地址)"下使用默认的初始化服务地址https//star Spring.io进行Spring Boot项目创建(注意使用快速方式创建Spring Boot项目时,所在主机须在联网状态下)


使用Spring Initializr方式构建的Spring Boot项目会默认生成项目启动类、存放前端静态资源和页面的文件夹、编写项目配置的配置文件以及进行项目单元测试的测试类

  • 创建一个用于Web访问的Controller
    com.study包下创建名称为controller的包,在该包下创建一个请求处理控制类HelloController,并编写一个请求处理方法(注意∶将项目启动类SpringBootDemoApplication移动到com.study包下)
@RestController // 该注解为组合注解,等同于spring中eController+eResponseBody注解
public class DemoController {
    @RequestMapping("/demo")
    public String demo(){
        return "你好 spring Boot";
    }
}
  • 运行项目
    运行主程序启动类SpringbootDemoApplication,项目启动成功后,在控制台上会发现Spring Boot项目默认启动的端口号为8080,此时,可以在浏览器上访问 http∶//localhost8080/hello

    页面输出的内容是hello Spring Boot",至此,构建Spring Boot项目就完成

附∶解决中文乱码∶
解决方法一∶

@RequestMapping(produces = "application/json; charset=utf-8")

解决方法二∶

#设置响应为utf-8
spring.http.encoding.force-response=true

单元测试与热部署

  • 单元测试
    开发中,每当完成一个功能接口或业务方法的编写后,通常都会借助单元测试验证该功能是否正确。Spring Boot对项目的单元测试提供了很好的支持,在使用时,需要提前在项目的pom.xml文件中添加spring-boot-starter-test测试依赖启动器,,可以通过相关注解实现单元测试

演示∶
1.添加spring-boot-starter-test测试依赖启动器
在项目的pom.xml文件中添加spring-boot-starter-test测试依赖启动器,示例代码如下∶


    org.springframework.boot
    spring-boot-starter-test
    test

注意∶使用Spring Initializr方式搭建的Spring Boot项目,会自动加入spring-boot-startertest测试依赖启动器,无需再手动添加

  1. 编写单元测试类和测试方法
    使用Spring Initilizr方式搭建的Spring Boot项目,会在src.testjava测试目录下自动创建与项目主程序启动类对应的单元测试类
@RunWith(SpringRunner.class) // 测试启动器,并加载Spring Boot测试注解
@SpringBootTest // 标记为Spring Boot单元测试类,并加载项目的Applicationcontext上下文环境
class SpringbootDemoApplicationTests {
    @Autowired
    private DemoController demoController;
    // 自动创建的单元测试方法实例
    @Test
    void contextLoads() {
        String demo = demoController.demo();
        System.out.println(demo);
    }
}

上述代码中,先使用@Autowired注解注入了DemoController实例对象,然后在contextLoads0方法中调用了DemoController类中对应的请求控制方法contextLoadst),并输出打印结果


  • 热部署
    在开发过程中,通常会对一段业务代码不断地修改测试,在修改之后往往需要重启服务,有些服务需要加载很久才能启动成功,这种不必要的重复操作极大的降低了程序开发效率。为此,Spring Boot框架专门提供了进行热部署的依赖启动器,用于进行项目热部署,而无需手动重启项目

演示∶
1.添加spring-boot-devtools热部署依赖启动器
在Spring Boot项目进行热部署测试之前,需要先在项目的pom.xml文件中添加spring-boot-devtools热部署依赖启动器∶



    org.springframework.boot
    spring-boot-devtools

由于使用的是IDEA开发工具,添加热部署依赖后可能没有任何效果,接下来还需要针对IDEA开发工具进行热部署相关的功能设置

2.IDEA工具热部署设置
选择IDEA工具界面的【File】->【Settings】选项,打开Compiler面板设置页面


选择Build下的Compiler选项,在右侧勾选"Build project automatically"选项将项目设置为自动编译,单击【Apply】→【OK】按钮保存设置
在项目任意页面中使用组合快捷键"Ctrl+Shift+Alt+/"打开Maintenance选项框,选中并打开Regstry页面,具体如图1-17所示



列表中找到compiler.automake.allow.whenapprunning,将该选项后的Value值勾选,用于指定IDEA工具在程序运行过程中自动编译,最后单击【Close】按钮完成设置

  1. 热部署效果测试
    启动http∶/localhost∶8080/hello

页面原始输出的内容是"hello Spring Boot"。

为了测试配置的热部署是否有效,接下来,在不关闭当前项目的情况下,将DemoController类中的请求处理方法hello0的返回值修改为"你好,Spring Boot"并保存,查看控制台信息会发现项目能够自动构建和编译,说明项目热部署生效



可以看出,浏览器输出了"你好,Spring Boot",说明项目热部署配置成功

全局配置文件

全局配置文件能够对一些默认配置值进行修改。Spring Boo使用一个application.properties或者application.yaml的文件作为全局配置文件,该文件存放在src/main/resource目录或者类路径的/config,一般会选择resource目录。接下来,将针对这两种全局配置文件进行讲解∶

  • application.properties配置文件
    使用Spring Initializr方式构建Spring Boot项目时,会在resource目录下自动生成一个空的application.properties文件,Spring Boot项目启动时会自动加载application.properties文件。

我们可以在application.properties文件中定义Spring Boot项目的相关属性,当然,这些相关属性可以是系统属性、环境变量、命令参数等信息,也可以是自定义配置文件名称和位置

server.port=8081
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.config.additional-location=
spring.config.location=
spring.config.name=application

接下来,通过一个案例对Spring Boot项目中application.properties配置文件的具体使用进行讲解
演示∶
预先准备了两个实体类文件,后续会演示将applicationproperties配置文件中的自定义配置属性注入到Person实体类的对应属性中
(1)先在项目的com.study包下创建一个pojo包,并在该包下创建两个实体类Pet和Person

public class Pet {
    private String type;
    private String name;
    //省略属性getxX()和setxX()方法
    // 省略tostring()方法
}
package com.study.pojo;

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

import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "person") //将配置文件中以person开头的属性注入到该类中
public class Person {


    private int id;            //id
    private String name;      //名称
    private List hobby;       //爱好
    private String[] family; //家庭成员
    private Map map;
    private Pet pet;          //宠物

    //省略属性getxX()和setxX()方法
    // 省略tostring()方法
}

@ConfigurationProperties(prefix="person"注解的作用是将配置文件中以person开头的属性值通过setXX)方法注入到实体类对应属性中

@Component注解的作用是将当前注入属性值的Person类对象作为Bean组件放到Spring容器中,只有这样才能被@Configuration Properties注解进行赋值

(2)打开项目的resources目录下的application.properties配置文件在该配置文件中编写需要对Person类设置的配置属性


编写application.properties配置文件时,由于要配置的Person对象属性是我们自定义的,Spring Boot 无法自动识别,所以不会有任何书写提示。在实际开发中,为了出现代码提示的效果来方便配置,在使用@ConfigurationProperties注解进行配置文件属性值注入时,可以在pom.xml文件中添加一个Spring Boot提供的配置处理器依赖∶


    org.springframework.boot
    spring-boot-configuration-processor
    true

在pom.xml中添加上述配置依赖后,还需要重新运行项目启动类或者使用"Ctr1+F9快捷键(即Build Project重构当前Spring Boot项目方可生效

(3)查看apliction.proprties配置文件是否正确,同时查看属性配置效果,打开通过IDEA工具创建的项目测试类,在该测试类中引入Person实体类Bean,并进行输出测试

@RunWith(SpringRunner.class)  //测试启动器,并加载spring boot测试注解
@SpringBootTest //标记该类为spring boot单元测试类,并加载项目的applicationContext上下文环境
class Springboot01DemoApplicationTests {

    //入门案例测试
    @Autowired
    private HelloController helloController;

    @Test
    void contextLoad1() {
        String demo = helloController.demo();
        System.out.println(demo);
    }
}

打印结果∶



可以看出,测试方法configurationTest(运行成功,同时正确打印出了Person实体类对象。至此,说明application.properties配置文件属性配置正确,并通过相关注解自动完成了属性注入

  • application.yaml配置文件
    YAML文件格式是Spring Boot支持的一种SON超集文件格式,相较于传统的Properties配置文件,YAML文件以数据为核心,是一种更为直观且容易被电脑识别的数据序列化格式。application.yam配置文件的工作原理和application.properties是一样的,只不过yam格式配置文件看起来更简洁一些。
    ● YAML文件的扩展名可以使用.yml或者.yaml。
    ● application.yml文件使用"key∶(空格)value"格式配置属性,使用缩进控制层级关系。
    这里,针对不同数据类型的属性值,介绍一下YAML

(1)value值为普通数据类型(例如数字、字符串、布尔等)
当YAML配置文件中配置的属性值为普通数据类型时,可以直接配置对应的属性值,同时对于字符串类型的属性值,不需要额外添加引号,示例代码如下

server:
    port: 8081
    path: /hello

上述代码用于配置servert的port和path属性,port和path属于一个级别
(2)value值为数组和单列集合
当YAML配置文件中配置的属性值为数组或单列集合类型时,主要有两种书写方式∶缩进式写法和行内式写法。
其中,缩进式写法还有两种表示形式,示例代码如下

person:
  hobby:
    - play
    - read
    - sleep

或者使用如下示例形式

person:
  hobby:
    play,
    read,
    sleep

上述代码中,在YAML配置文件中通过两种缩进式写法对person对象的单列集合(或数组)类型的爱好hobby赋值为play、read和sleep。其中一种形式为"(空格)属性值",另一种形式为多个属性值之前加英文逗号分隔(注意,最后一个属性值后不要加逗号)。

person:
  hobby: [play,read,sleep]

通过上述示例对比发现,YAML配置文件的行内式写法更加简明、方便。另外,包含属性值的中括号"T"还可以进一步省略,在进行属性赋值时,程序会自动匹配和校对
(3)value值为Map集合和对象
当YAML配置文件中配置的属性值为Map集合或对象类型时,YAML配置文件格式同样可以分为两种书写方式∶缩进式写法和行内式写法。
其中,缩进式写法的示例代码如下

person:
  map:
  k1: v1
  k2: v2

对应的行内式写法示例代码如下

person:
  map: {k1: v1,k2: v2}

在YAML配置文件中,配置的属性值为Map集合或对象类型时,缩进式写法的形式按照YAML文件格式编写即可,而行内式写法的属性值要用大括号"0"包含。

接下来,在Properties配置文件演示案例基础上,通过配置application.yam配置文件对Person对象进行赋值,具体使用如下

(1)在项目的resources目录下,新建一个application.yaml配置文件,在该配置文件中编写为Person类设置的配置属性

# 对实体对象person进行属性配置
person:
  id: 2
  name: lucy
  hobby: [吃饭,睡觉,打豆豆]
  family: [father,mother]
  map: {k1: v1,k2: v2}
  pet: {type: dog,name: 旺财}

(2)再次执行测试



可以看出,测试方法configurationTest(同样运行成功,并正确打印出了Person实体类对象。

需要说明的是,本次使用application.yam配置文件进行测试时需要提前将application.properties配置文件中编写的配置注释,这是因为application.properties配置文件会覆盖aplication.yaml配置文件

配置文件属性值的注入

使用Spring Boot全局配置文件设置属性时∶如果配置属性是Spring Boo已有属性,例如服务端口server.port,那么Spring Boot内部会自动扫描并读取这些配置文件中的属性值并覆盖默认属性。

如果配置的属性是用户自定义属性,例如刚刚自定义的Person实体类属性,还必须在程序中注入这些配置属性方可生效。

Spring Boot支持多种注入配置文件属性的方式,下面来介绍如何使用注解@ConfigurationProperties 和@Value注入属性

  • 使用@ConfigurationProperties注入属性
    Spring Boot提供的@ConfigurationProperties注解用来快速、方便地将配置文件中的自定义属性值批量注入到某个Bean对象的多个对应属性中。假设现在有一个配置文件,如果使用@ConfigurationProperties注入配置文件的属性,示例代码如下∶
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private int id; 
    // 属性setXX() 方法
    public void setId(int id) {
        this.id = id;
    }
}

上述代码使用@Component和@ConfigurationProperties(prefix="person"将配置文件中的每个属性映射到person类组件中。
需要注意的是,使用@ConfigurationProperties

  • 使用@Value注入属性
    @Value注解是Spring框架提供的,用来读取配置文件中的属性值并逐个注入到Bean对象的对应属性中,Spring Boot框架从Spring框架中对@Value注解进行了默认继承,所以在Spring Boot框架中还可以使用该注解读取和注入配置文件属性值。使用@Value注入属性的示例代码如下
@Component
public class Person {
    @Value("${person.id}")
    private int id; 
}

上述代码中,使用@Component和@Value注入Person实体类的id属性。其中,@Value不仅可以将配置文件的属性注入Person的id属性,还可以直接给id属性赋值,这点是@ConfigurationProperties不支持的

演示@Value注解读取并注入配置文件属性的使用∶
(1)在com.study.pojo包下新创建一个实体类Student,并使用@Value注解注入属性

@Component
public class Student {

    @Value("${person.id}")
    private int id;
    @Value("${person.name}")
    private String name;

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

Student类使用@Value注解将配置文件的属性值读取和注入。
从上述示例代码可以看出,使用@Value注解方式需要对每一个属性注入设置,同时又免去了属性的setXX()方法

(2)再次打开测试类进行测试

@Autowired
private Student student;
@Test
public void studentTest() {
    System.out.println(student);
}

打印结果:



可以看出,测试方法studentTest(运行成功,同时正确打印出了Student实体类对象。需要说明的是,本示例中只是使用@Value注解对实例中Student对象的普通类型属性进行了赋值演示,而@Value注解对于包含Map集合、对象以及YAML文件格式的行内式写法的配置文件的属性注入都不支持,如果赋值会出现错误

自定义配置

spring Boot免除了项目中大部分的手动配置,对于一些特定情况,我们可以通过修改全局配置文件以适应具体生产环境,可以说,几乎所有的配置都可以写在application.peroperties文件中,Spring Boot会自动加载全局配置文件从而免除我们手动加载的烦恼。但是,如果我们自定义配置文件,Spring Boot 是无法识别这些配置文件的,此时就需要我们手动加载。接下来,将针对Spring Boot的自定义配置文件及其加载方式进行讲解

  • 使用@PropertySource加载配置文件
    对于这种加载自定义配置文件的需求,可以使用@PropertySource注解结合@Configuration注解配置类的方式来实现。@PropertySource注解用于指定自定义配置文件的具体位置和名称。同时,为了保证Spring Boot能够扫描该注解,还需要类上添加@Configuration注解将实体类作为自定义配置类。当然,如果需要将自定义配置文件中的属性值注入到对应类的属性中,可以使用@ConfigurationProperties或者@Value注解进行属性值注入
    演示∶(
    1)打开Spring Boot项目的resources目录,在项目的类路径下新建一个test.properties自定义配置文件,在该配置文件中编写需要设置的配置属性
#对实体类对象MyProperties进行属性配置
test.id=110
test.name=test

(2)在com.study.pojo包下新创建一个配置类MyProperties,提供test.properties自定义配置文件中对应的属性,并根据@PropertySource注解的使用进行相关配置

@Configuration //自定义配置类
@PropertySource("classpath:test.properties") //指定自定义配置文件位置和名称
@EnableConfigurationProperties(MyProperties.class) //开启对应配置类的属性注入功能
@ConfigurationProperties(prefix = "test") //指定配置文件注入属性前缀
public class MyProperties {
    private int id;
    private String name;
    //省略属性getXx()和setXX()方法
    //省略toString()方法
}

主要是一个自定义配置类,通过相关注解引入了自定义的配置文件,并完成了自定义属性值的注入。针对示例中的几个注解,具体说明如下
● @Configuration注解表示当前类是一个自定义配置类,并添加为Spring容器的组件,这里也可以使用传统的@Component注解;
● @PropertySource("classpath∶test.properties"注解指定了自定义配置文件的位置和名称,此示例表示自定义配置文件为classpath类路径下的test.properties文件;
● @ConfigurationProperties(prefix="test"注解将上述自定义配置文件test.properties中以test开头的属性值注入到该配置类属性中。
● 如果配置类上使用的是@Component注解而非@Configuration注解,那么@EnableConfigurationProperties注解还可以省略
(3)进行测试

@Autowired
private MyProperties myProperties;
@Test
public void myPropertiesTest() {
    System.out.println(myProperties);
}

打印结果:


  • 使用@Configuration编写自定义配置类
    在Spring Boot框架中,推荐使用配置类的方式向容器中添加和配置组件

在Spring Boot框架中,通常使用@Configuration注解定义一个配置类,Sprig Boot会自动扫描和识别配置类,从而替换传统Spring框架中的XML配置文件。

当定义一个配置类后,还需要在类中的方法上使用@Bean注解进行组件配置,将方法的返回对象注入到Spring容器中,并且组件名称默认使用的是方法名,当然也可以使用@Bean注解的name或value属性自定义组件的名称
演示∶
(1)在项目下新建一个com.study.config包,并在该包下新创建一个类MyService,该类中不需要编写任何代码

public class MyService {
}

创建了一个空的MyService类,而该类目前没有添加任何配置和注解,因此还无法正常被Sprig Boot扫描和识别
(2)在项目的com.study.config包下,新建一个类MyConfig,并使用@Confguration注解将该类声明一个配置类,内容如下∶

@Configuration //定义该类是一个配置类
public class MyConfig {
    @Bean //将返回值对象作为组件添加到spring容器中,该组件id默认为方法名
    public MyService myService(){
        return new MyService();
    }
}

MyConfig是@Configuration注解声明的配置类(类似于声明了一个XML配置文件),该配置类会被Spring Boot自动扫描识别;使用@Bean注解的myService()方法,其返回值对象会作为组件添加到了Spring容器中(类似于XML配置文件中的标签配置),并且该组件的id默认是方法名myService
(3)测试类

@Autowired
private ApplicationContext applicationContext;
@Test
public void iocTest() {
    System.out.println(applicationContext.containsBean("myService"));
}

上述代码中,先通过@Autowired注解引入了Spring容器实例ApplicationContext,然后在测试方法iocTest()中测试查看该容器中是否包括id为myService的组件。

执行测试方法iocTest(),查看控制台输出效果,结果如下∶



从测试结果可以看出,测试方法locTest(运行成功,显示运行结果为true,表示Spirng的IOC容器中也已经包含了id为myService的实例对象组件,说明使用自定义配置类的形式完成了向Spring容器进行组件的添加和配置

随机数设置及参数间引用

在Spring Boot配置文件中设置属性时,除了可以像前面示例中显示的配置属性值外,还可以使用随机值和参数间引用对属性值进行设置。下面,针对配置文件中这两种属性值的设置方式进行讲解

  • 随机值设置
    在Spring Boo配置文件中,随机值设置使用到了Spring Boot内嵌的RandomValuePropertySource 类,对一些隐秘属性值或者测试用例属性值进行随机值注入
    随机值设置的语法格式为(randomxx,x表示需要指定生成的随机数类型和范围,它可以生成随机的整数、uid或字符串,示例代码如下
my.secret=${random.value} // 配置随机值
my.number=${random.int} // 配置随机整数
my.bignumber=${random.long} // 配置随机long类型数
my.uuid=${random.uuid} // 配置随机uuid类型数
my.number.less.than.ten=${random.int(10)} // 配置小于10的随机整数
my.number.in.range=${random.int[1024,65536]} // 配置范围在[1024,65536]之间的随机整数

上述代码中,使用RandomValuePropertySource类中random提供的随机数类型,分别展示了不同类型随机值的设置示例

  • 参数间引用

在Spring Boot配置文件中,配置文件的属性值还可以进行参数间的引用,也就是在后一个配置的属性值中直接引用先前已经定义过的属性,这样可以直接解析其中的属性值了。

使用参数间引用的好处就是,在多个具有相互关联的配置属性中,只需要对其中一处属性预先配置,其他地方都可以引用,省去了后续多处修改的麻烦

参数间引用的语法格式为${xx},xx表示先前在配置文件中已经配置过的属性名,示例代码如下

app.name=MyApp
app.description=${app.name} is a Spring Boot application

上述参数间引用设置示例中,先设置了"app.name=MyApp",将app.name属性的属性值设置为了MyApp;接着,在app.description属性配置中,使用$《app.name)对前一个属性值进行了引用

接下来,通过一个案例来演示使用随机值设置以及参数间引用的方式进行属性设置的具体使用和效果,具体步骤如下
(1)打开Spring Boot项目resources目录下的application.properties配置文件,在该配置文件中分别通过随机值设置和参数间引用来配置两个测试属性,示例代码如下

#随机值设置以及参数间引用配置
tom.age=${random.int[10,20]}
tom.description=tom的年龄可能是${tom.age}

在上述application.properties配置文件中,先使用随机值设置了tom.age属性的属性值,该属性值设置在了【10,20】之间,随后使用参数间引用配置了tom.description属性

(2)打开项目的测试类,在该测试类中新增字符串类型的description属性,并将配置文件中的tom.description属性进行注入,然后新增一个测试方法进行输出测试,示例代码如下

@Value("${tom.description}")
private String description;
@Test
public void placeholderTest() {
    System.out.println(description);
}

上述代码中,通过@Value("${tom.description"注解将配置文件中的tom.description属性值注入到了对应的description属性中,在测试方法placeholderTest()中对该属性值进行了输出打印。

执行测试方法placeholderTest(),查看控制台输出效果



可以看出,测试方法placeholderTest()运行成功,并打印出了属性description的注入内容,该内容与配置文件中配置的属性值保持一致。接着,重复执行测试方法placeholderTest(),查看控制台输出语句中显示的年龄就会在[10,20]之间随机显示

你可能感兴趣的:(SpringBoot 基础)