Spring Boot配置文件

文章目录

  • 一、关于配置文件
    • [1.1 配置文件有哪些](#1.1 配置文件有哪些)
    • [1.2 配置文件的重要性 --- 解决硬编码](#1.2 配置文件的重要性 --- 解决硬编码)
  • 二、配置文件格式
    • [2.1 通用知识](#2.1 通用知识)
    • [2.2 properties配置文件说明](#2.2 properties配置文件说明)
    • [2.3 yml配置文件说明](#2.3 yml配置文件说明)
  • 三、示例
    • [3.1 关于类型的匹配](#3.1 关于类型的匹配)
    • [3.2 配置对象](#3.2 配置对象)
    • [3.3 修改端口号](#3.3 修改端口号)
    • [3.4 使用自定义配置](#3.4 使用自定义配置)
    • [3.5 配置广告条](#3.5 配置广告条)
    • [3.6 验证码案例](#3.6 验证码案例)

一、关于配置文件

1.1 配置文件有哪些

  1. Spring的配置文件 :Spring给我们提供了一些默认配置(约定),可以让我们实现零配置。但也允许我们去修改 ---- >写在配置文件里
  2. pom.xml:也是一个配置文件。使我们可以通过 < dependency> ,让Maven帮我们去下载Jar包
  3. file --->settings:也对应着配置文件,只是给我们提供了图形化界面而已
  4. C盘中.开头的文件 :C盘中用户文件夹里,放的大多都是一些配置文件或缓存文件
    • . 开头的很多都是配置文件

1.2 配置文件的重要性 --- 解决硬编码

  1. 配置文件最重要的目的就是 解决硬编码的问题
    • 硬编码:直接往代码中嵌入数据,写死了,无法在不修改源代码的情况下进行更改
      • 比如如果我们把数据库的账号和密码直接写在代码中,如果本地上装的mysql和在Linux上装的mysql账号密码不同,这时候就需要修改代码,再部署到Linux服务器上。但如果部署出错了,此时就需要再次修改代码,然后再上传,十分繁琐
      • 编译问题:硬编码问题,是需要我们多次编译的,虽然我们目前修改配置文件的方式,也需要重启服务,编译让其生效。那是因为我们使用的技术并没有很先进,如果我们搭配了先进的框架,这些配置文件是可以做到立即生效的(热加载)。
        • 热加载:写的代码立即被加载进来且生效
        • 热部署:如果代码发生了变化,会重新部署
  2. 让我们自己进行配置:配置文件相当于提供了一个入口,让我们去配置,服务器会从这个入口读配置内容
  3. 什么样的数据适合放在配置文件中?:数据可能会改变且与程序的运行并没有什么关系

二、配置文件格式

2.1 通用知识

  1. 如何配置:配置就是让配置项按照格式的要求去写
  2. 配置是两方面的:一方面是我去设置了,另一方面是对方支持我配置的内容
  3. SpringBoot配置文件的常见三种格式 :可以理解为下面这三种都是语言,是通用的,Python、Go也可能在用
    • properties:
    • yaml:
    • yml:是yaml的简写,和yaml一模一样,只是名字不同
  4. Spring Boot的配置文件:Spring项目在启动时,会去寻找这个文件,并加载里面的内容,然后再去进行Bean的创建(初始化操作)
  5. SpringBoot只支持3个文件 :更改了文件名后无法生效(因为Spring Boot默认的配置文件就是application开头的)
    • application.properties:
    • application.yaml:
    • application.yml:
  6. 修改Spring Boot默认的配置文件 :Spring Boot默认的配置文件就是application开头的,我们可以去修改,但往往不去改,多此一举
    • 方法:启动Spring Boot时指定配置文件
    • Spring Boot如何启动:运行一个Java程序
      • 在IDEA中:点击运行就行,实际上是运行了main方法
      • 不在IDEA中:首先打一个Jar包,然后去运行我们这个Jar包
        • Jar包 VS war包:里面都是出来的class文件,通常我们会认为war包是一个web程序,不用特别纠结用哪个
        • 运行Jar包:把该包拖到 Linux服务器 上,通过java -jar XXX.jar 直接启动
  7. 如果存在多个配置文件怎么办? :properties的优先级更高
    • 对优先级的理解:不是说其他的不生效了,配置文件都生效,只是如果两个文件中都包含同一个配置,是以properties为主的
    • 开发时的使用:配置文件是可以替代的。企业开发中,我们通常只使用一个文件就可以完成配置了。而且如果用多个配置文件,一个配置项还要去多个文件中找,十分繁琐

2.2 properties配置文件说明

  1. 格式规范
    • key - value的形式,以 = 分割,后面加不加空格无所谓
    • key的格式建议是小写,单词之间使用.分割
java 复制代码
# 配置项⽬端⼝号
server.port=8080
#配置数据库连接信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8&

//中间的空行可以随便加
spring.datasource.username=root
spring.datasource.password=root
  1. 缺点分析
    • 有很多重复的部分,代码繁琐
    • 可读性差,当配置项很多时,看不出来配置项之间的关系

2.3 yml配置文件说明

  1. 非常注意格式,格式问题会导致bug
  2. 格式
    • key之间使用 【冒号 + 换行】分割
      • 空格的含义:每一行的空格代表的是"层次关系"
      • IDEA中 tab 与 空格 的关系:有些版本的IDEA默认把tab对标到空格上,我们在IDEA上可以用tab,但是实际上是要用空格的。
    • key和Value之间使用【冒号】赋值,Value前面的冒号后面一定要加空格
  3. yml 中一些特殊的表示
    • 用【~】表示 null:key: ~
    • 用【】、【''】、【""】表示 空字符串:key: 、key: ''、key: ""
      • 因为使用【】不太易读,所以我们会用单双引号的方式,提高可读性
      • 一般情况下,一个普通的字符串不需要加引号,但如果是空字符串的情况下,为了可读性,建议加上单双引号
  4. yml层次问题:yml文件的层次并不是两个空格,两个空格只是企业的规范。我们可以用任意空格表示层次,只要表示了即可。
  5. 不能重复
  6. yml优缺点
    • 优点
      • 带有换行,可读性高,写法简单,易于理解
      • 支持更多的数据类型,可以简单表达对象,数组,List,Map等数据形态
      • 支持更多的编程语言, 不止是Java中可以使用,在Golang, Python, Ruby, JavaScript中也可以使用。一个大项目,往往是由多个语言写出来的。
    • 缺点
      • 格式复杂,内容少的时候,就适合用了

三、示例

注意配置文件是可以替代的,不用管是properties还是yml

3.1 关于类型的匹配

  1. 关于自动匹配 :Spring会帮我们把配置文件中的值自动转换成接收的类型,并赋值
    • 保证能转:注意,此处只是帮我们自动转,但也是需要我们保证【能转】的。比如布尔类型就无法转为int类型
    • Spring MVC类似:Spring MVC中参数的接收也是如此,Spring会帮我们自动转换类型 + 赋值
  2. 单引号 VS 双引号 :单引号会对特殊字符进行转义,双引号不会进行转义。下面的例子是如果出现了【\n】
    • 单引号:使用单引号时,内容是\n,而不是换行
    • 双引号:使用双引号时,\n变成了换行,也就是\n本来的含义
java 复制代码
String:
  str1: This is \n str1
  str2: 'This is \n str2'
  str3: "This is \n str3"
java 复制代码
@RestController
public class YmlController {
    @Value("${String.str1}")
    private String str1;
    @Value("${String.str2}")
    private String str2;
    @Value("${String.str3}")
    private String str3;

    @PostConstruct
    public void  init(){
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
    }
}
  1. 为什么日志要从下往上看:下面出现的问题,会引发上方的问题,层层递进

3.2 配置对象

在yml中配置对象

  1. 方式 :一个变量一个变量地去读
    • @Value注解:使用@Value,一个变量一个变量地去读
    • @ConfigurationProperties:把配置文件中的数据作为一个对象读取,并且一一对应赋值
      • prefix:前缀,表示在yml文件中你配置的这个对象的前缀是什么
  2. 接收配置文件中设置的值
java 复制代码
@Component
@ConfigurationProperties(prefix = "student")
@Data
public class Student {
    private Integer id;
    private String name;
    private Integer age;
}
  1. 配置文件
java 复制代码
student:
  id: 18
  name: zhangsan
  age: 12
  1. 使用
java 复制代码
@RestController
public class YmlController {
    @Autowired
    private Student student;
    @PostConstruct
    public void  init(){
        System.out.println(student);
    }
}

在yml中配置集合/数组

  1. 配置文件:并列的关系,要加【-】,且后面要加空格,如果没加会直接当成一整个字符串赋值过去
java 复制代码
person:
  name:
    - zhangsan
    - lisi
    - wangwu
  1. 接收配置文件中设置的值
    • 两种接受方式:
      • 列表:private List name
      • 数组:private String[] name;
java 复制代码
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private List<String> name;

//    private String[] name;   还可以使用数组去接受
}
  1. 使用
java 复制代码
@RestController
public class YmlController {
    @Autowired
    private Person person;
    
    @PostConstruct
    public void  init(){
        System.out.println(person.getName().toString());
    }
}

yml配置Map

  1. 配置文件
java 复制代码
person:
  name:
    - zhangsan
    - lisi
    - wangwu
  map:
    k1: a
    k2: b
    k3: c
  1. 接收配置文件中设置的值
java 复制代码
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String[] name;

    private HashMap<String, String> map;
}
  1. 使用
java 复制代码
@RestController
public class YmlController {
    @Autowired
    private Person person;
    
    @PostConstruct
    public void  init(){
        System.out.println(person.getName().toString());
        System.out.println(person.getMap().toString());

    }
}

3.3 修改端口号

  1. 关于配置项的查询:去官方文档上查阅
  2. server.port :修改Spring内置的Tomcat的端口号
    • 关于端口号:
      • 范围0~65535
      • 前0 ~1024的端口大多已经被一些知名的服务器占用了,不推荐使用
      • 注意数据库默认端口号是3306,也别去占用
java 复制代码
server.port=9090    //server.port是Spring给我们提供的一个配置文件的配置项

3.4 使用自定义配置

  1. 使用原理:配置项原本就是由程序员自定义的,像Spring Boot的配置项就是由他们的开发人员自定义然后提供给我们,然后我们都这么用。也因此,我们也可以自定义配置项,然后使用。
  2. 代码解析 :
    • 原理:@Value注解读取到【demo.key1】中的内容后,Value数据会自动匹配成String类,然后被赋值给key1
    • @Value:可以帮我们去读取配置文件中的内容
    • 配置项中的value值:不需要加单双引号,被读取后是可以根据接收的类型自动匹配的,所以哪怕配置项是数字我们也可以直接写
    • $符号:可以理解为【去从里面的这个变量取到值】
      • 如果不加,此时就变成了把【demo.key1】变成一个字符串然后赋值给key1,即我们获取到的结果不是helloXXX,而是demo.key1
  3. properties格式下
java 复制代码
//配置文件代码
demo.key1 = hello, properties
java 复制代码
@RestController
public class propertiesController {
    @Value("${demo.key1}")
    private String key1;

    @RequestMapping("/readkey")
    public String readKey(){
        return key1;
    }
}
  1. yml 格式下
    • @PostConstruct注解:表示初始化
      • Spring会帮我们创建完类和对象后,且他还没有对外提供服务时,执行这个初始化方法
java 复制代码
spring:
  datasource:
    url: jdbc:mysql://127.0.0.0:3306/dbname?characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
  banner:
    location: banner.txt


//中间可以随便加空行
demo:
  key1: hello, poerties
  key2: hello, yml
  key3: 10
java 复制代码
@RestController
public class YmlController {
    @Value("${demo.key2}")
    private String key2;

    @PostConstruct
    public void  init(){
        System.out.println(key2);
    }
}

3.5 配置广告条

3.6 验证码案例

  1. 实现方式 :kaptcha插件
    • 我们可以自己去实现,但那比较复杂,直接用插件即可
    • 验证码前后端都可以去实现,此处我们是用后端kaptcha插件实现
    • 要注意Spring Boot的版本问题,如果Spring Boot版本太高,是无法使用的
  2. 引入依赖 :我们把Jar包引进来后,虽然它们不在我们自己写的代码中,但是已经包含在项目里了,是可以直接使用的
    • 使用Edit Startern,由Spring帮我们管理依赖:这里只是提供了一些常见的框架的依赖,小众的还是需要自己添加的
    • 手动添加
xml 复制代码
<dependency>
	<groupId>com.oopsguy.kaptcha</groupId>
	<artifactId>kaptcha-spring-boot-starter</artifactId>
	<version>1.0.0-beta-2</version>
</dependency>
  1. 进行配置项的设置
    • 此处生成的验证码被放在了session中
  2. 查看生成的验证码
    此时用Get方法以【/home/captcha】和【/admin/captcha】路径可以访问Kacptcha生成的验证码,刷新会生成新的
  3. 前端代码
    • img里的src:本机地址(分相对和绝对)、网络地址(打开图片 + 复制图片地址)、后端地址
java 复制代码
$("#checkCaptcha").click(function () {
    $.ajax({
        type: "get",
        url: "/admin/check",
        data:{
            captcha: $("#inputCaptcha").val()
        },

        success: function (result){
            if (result){
                location.href = "success.html";
            }else{
                alert("验证码错误")
            }
        }
    });
});
  1. 后端代码
    • 为什么要定义常量:提高代码的可读性(value太长影响阅读) + 解耦合
    • 常量的定义:只是企业开发的建议
      • 【key】全部大写,单词之间使用下划线分割
      • 【value】通常是小写,以下划线分割(下面示例中其实并不规范)
    • 定义时间:使用Long类型接收 + 用表达式去写。60表示的是60s,1000L表示的是1000毫秒
    • 查看Session中的值:
java 复制代码
@RestController
@RequestMapping("/admin")
public class CaptchaController {
    private static final String KAPTCHA_SESSION_KEY = "ADMIN_KAPTCHA_SESSION_KEY";
    //验证码时间
    private static final String KAPTCHA_SESSION_DATE = "ADMIN_KAPTCHA_SESSION_DATE";
    //有效时间
    private static final Long SESSION_TIMEOUT = 60 * 1000L;


    @RequestMapping("/check")
    public Boolean check(String captcha, HttpSession session){
        if (!StringUtils.hasLength(captcha)){
            return false;
        }

        String savaCaptcha = (String)session.getAttribute(KAPTCHA_SESSION_KEY);
        Date saveDate = (Date) session.getAttribute(KAPTCHA_SESSION_DATE);

        if (captcha.equals(savaCaptcha)){
            if (saveDate==null || System.currentTimeMillis() - saveDate.getTime()<SESSION_TIMEOUT){
                return true;
            }
        }

        return false;
    }
}
相关推荐
小灰灰__8 分钟前
IDEA加载通义灵码插件及使用指南
java·ide·intellij-idea
夜雨翦春韭11 分钟前
Java中的动态代理
java·开发语言·aop·动态代理
程序媛小果32 分钟前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
追风林37 分钟前
mac m1 docker本地部署canal 监听mysql的binglog日志
java·docker·mac
芒果披萨1 小时前
El表达式和JSTL
java·el
许野平1 小时前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
duration~2 小时前
Maven随笔
java·maven
zmgst2 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD2 小时前
前后端分离,Jackson,Long精度丢失
java
blammmp2 小时前
Java:数据结构-枚举
java·开发语言·数据结构