Spring详解四种加载配置项的方法

目录
  • 1.spring加载yml文件
  • 2.spring 加载 properties 文件
  • 3.spring加载系统磁盘(properties)文件
  • 4.spring加载xml文件
  • 5.Java基于InputStream读取properties配置文件

本文默认 spring 版本是 spring5

1 spring 加载 yml 文件

2 spring 加载 properties 文件

3 spring 加载 系统磁盘 文件

4 spring 加载 xml 文件

5 Java 基于 InputStream 读取 properties 配置文件

spring框架默认加载配置:

resources 下的文件名称为application的 application.yml 以及 application.properties, 默认会被spring加载到容器 Container

中,如果他们有重复的配置项,会被默认合并,并且 application.properties优先级更高. 下面的 LoadYmlTest.java 有详细解释

示例:

# application.yml 
user:
  userName: ifredom_name
  age: 30  # 定义了属性 age

# application.properties 
# 也定义了属性 age
user.age=99
user.sex=2

package com.example.commonmybatisplus.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
 * 配置类
 * spring默认规则:自动将 resources 下名称为 application 的 yml 和 properties 文件加载为bean
 * 注意: 一定要有 get 和 set 方法,此处通过 @Data 注解注入
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "user")
public class LoadPropertySourceYmlConfig {
    private String userName;
    private int sex;
    private int age;
}
package com.example.commonmybatisplus.PropertySourceTest;
import com.example.commonmybatisplus.config.LoadPropertySourceYmlConfig;
import com.example.commonmybatisplus.entity.UserEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
/**
 * 测试
 * 从结果可知: age的值为99,证明了 properties的优先级高于yml
 * 事实上,spring最早支持 properties 类型文件,后来才支持的yml,所以为了兼容
 * 一定是 properties > yml 优先级。
 * 即便将来又出现了 XXX.abc 文件
 * 那么为了兼容,永远时最早支持的优先级更高,也就是 properties > yml >abc
 */
@SpringBootTest
public class LoadYmlTest {
    @Autowired
    private LoadPropertySourceYmlConfig ymlConfig;
    @Test
    public void testYml() {
        String name = ymlConfig.getUserName();
        int sex = ymlConfig.getSex();
        int age = ymlConfig.getAge();
        System.out.println(name); // ifredom
        System.out.println(sex);  // 2
        System.out.println(age);  // 99
    }
}

1.spring加载yml文件

上面已经通过默认的方式演示了如何加载默认的application.yml,但是更好的写法是,将我们自定义的配置独立为一个单独的文件。

比如我们开发微信公众号,小程序开发时,就需要用到配置,此时的配置就应该独立为一个额外的文件。(此处将演示加载为 List)

一共有3步:

  • 创建配置文件 wechat-config.yml
  • 定义配置类 LoadPropertySourceYmlConfig,用来加载yml中的数据 (指定配置类的加载器) (因为 spring 配置类的默认加载器是 PropertiesLoader加载器,所以我们需要自定义 yml加载器。可以自行查看注解 @PropertySource 源码)
  • 自定义配置类加载器 YamlSourceFactory,继承Spring提供的默认配置类构造器 DefaultPropertySourceFactory
  • 测试

示例:

# main/resources/chat-config.yml

#微信小程序的appid
appid: app-xxx
#微信小程序的Secret
secret: secretxxx
#微信小程序消息服务器配置的token
token: token-xxx
#微信小程序消息服务器配置的EncodingAESKey
aesKey: aesKey-xxx

wx:
  configs:
    #微信小程序的appid
    - appid: app1
      #微信小程序的Secret
      secret: secret1
      #微信小程序消息服务器配置的token
      token: token1
      #微信小程序消息服务器配置的EncodingAESKey
      aesKey: aesKey1

#微信小程序的appid
    - appid: appid2
      #微信小程序的Secret
      secret: secret2
      #微信小程序消息服务器配置的token
      token: token2
      #微信小程序消息服务器配置的EncodingAESKey
      aesKey: aesKey2

def-my-var1: 定义配置属性var1
def-my-var2: 定义配置属性var2

这里需要注意,在上面的配置文件中是 wx.configs, 因此在配置类中,也必须用同名的 configs 来接收

package com.example.commonmybatisplus.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * 注意:factory的值,为接下来自定义的加载器
 */
@Data
@Configuration
@PropertySource(value = "classpath:wechat-config.yml", factory = YamlSourceFactory.class)
@ConfigurationProperties(prefix = "wx")
public class LoadPropertySourceYmlConfig {
    private List<Config> configs;
    @Data
    public static class Config {
        private String appid;
        private String secret;
        private String token;
        private String aesKey;
    }
    private String appid;
    private String secret;
    private String token;
    private String aesKey;
}
// 自定义记载器
package com.example.commonmybatisplus.config;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import java.io.IOException;
import java.util.List;
public class YamlSourceFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        // 这里使用Yaml配置加载类来读取yml文件信息
        List<PropertySource<?>> sources = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
        return sources.get(0);
    }
}

测试结果

package com.example.commonmybatisplus.PropertySourceTest;
import com.example.commonmybatisplus.config.LoadPropertySourceYmlConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
/**
 * @Author ifredomvip@gmail.com
 * @Date 2022/6/15 10:40
 * @Version 1.0.0
 * @Description
 **/
@SpringBootTest
public class LoadYmlTest {
    @Autowired
    private LoadPropertySourceYmlConfig ymlConfig;
    @Test
    public void testYml() {
        String appidXXX = ymlConfig.getAppid();
        String secretXXX = ymlConfig.getSecret();
        System.out.println("单独的属性配置---appidXXX: " + appidXXX);
        System.out.println("单独的属性配置---secretXXX: " + secretXXX);
        // 以下演示 配置项作为 List
        List<LoadPropertySourceYmlConfig.Config> configs = ymlConfig.getConfigs();
        // 迭代 List 每一项
        for (LoadPropertySourceYmlConfig.Config config : configs) {
            System.out.println("属性作为List: " + config);
        }
        // 获取List种的某一项
        LoadPropertySourceYmlConfig.Config configFirst = configs.get(0);
        String appidFirst = configFirst.getAppid();
        System.out.println("List的第一项: " + configFirst);
        System.out.println("List的第一项的其中一个属性: " + appidFirst);
        LoadPropertySourceYmlConfig.Config configSecond = configs.get(1);
        String secretSecond = configSecond.getSecret();
        System.out.println("List的第二项: " + configSecond);
        System.out.println("List的第二项的其中一个属性: " + secretSecond);
    }
}

2.spring 加载 properties 文件

从上一步我们已经知道了, spring 默认使用 properties 文件的加载器。因此,我们可以少一步构造加载器

  • 创建配置文件 alibaba-config.properties
  • 定义配置类 LoadPropertySourceConfig,用来加载yml中的数据
  • 测试

# main/resources/alibaba-config.properties
ali-yun.username="ifredom"
ali-yun.password="123456"
ali-yun.blog="http://www.ifredom.com"

package com.example.commonmybatisplus.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Data
@Configuration
@PropertySource("classpath:alibaba-config.properties")
@ConfigurationProperties(prefix = "aliyun")
public class LoadPropertySourceConfig {
    private String username;
    private String password;
    private String blog;
}

测试:

package com.example.commonmybatisplus.PropertySourceTest;
import com.example.commonmybatisplus.config.LoadPropertySourceConfig;
import com.example.commonmybatisplus.config.LoadPropertySourceYmlConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
/**
 * @Author ifredomvip@gmail.com
 * @Date 2022/6/15 10:40
 * @Version 1.0.0
 * @Description
 **/
@SpringBootTest
public class LoadYmlTest {
    @Autowired
    private LoadPropertySourceYmlConfig ymlConfig;
    @Autowired
    private LoadPropertySourceConfig propertyConfig;
    @Test
    public void testProperty() {
        String username = propertyConfig.getUsername();
        String password = propertyConfig.getPassword();
        String blog = propertyConfig.getBlog();
        System.out.println("单独的属性配置---username: " + username);
        System.out.println("单独的属性配置---password: " + password);
        System.out.println("单独的属性配置---blog: " + blog);
    }
    @Test
    public void testYml() {
    }
}

细心的同学应该发现了,在配置文件中定义的是ali-yun中间明明有一个短横线,读取属性的时候怎么没了?

这是因为 Spring 配置加载器类对诸如 空格,下划线,短横线,大小写都做了替空处理,也就是:配置文件是不分大小写的; 并且 下划线,短横线也会忽略: user_name -> username, pass-word -> password.因此取名你可以很随意

3.spring加载系统磁盘(properties)文件

有时候我们会需要加载其他项目下的数据库,而配置文件并不在当前项目路劲下,因此需要指定文件路径。

  • 磁盘路径可以是相对路径,绝对路径,也可以通过系统属性值指定变量
  • 相对路径,文件在应用根目录下:@PropertySource(value = {"file:project1.properties"})
  • 相对路径,文件在应用根目录下:@PropertySource(value = {"file:./project1.properties"})
  • 绝对路径,在指定的路径下:@PropertySource(value = {"file:D:\\project\\project1.properties"})
  • 通过系统属性值指定变量:@PropertySource(value = {"file:${user.dir}/project1.properties"})

由于加载xml文件还需要对xml文件进行解析,此处不做讲解。仅仅使用 properties 文件做例子。 示例:

#  位于D盘下的配置文件 D:\project1.properties
driverClassName=com.mysql.cj.jdbc.Driver
url="https://www.ifredom.com"
username="ifredom"
password="123456"

由于配置文件没有前缀,因此 配置类 必须使用@Value()进行映射

package com.example.commonmybatisplus.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Data
@Configuration
@PropertySource(value = {"file:D:\\project1.properties"})
public class LoadDiskConfig {
    @Value("driverClassName")
    private String driverClassName;
    @Value("url")
    private String url;
    @Value("username")
    private String username;
    @Value("password")
    private String password;
}
/**
 * 测试
 */
@SpringBootTest
public class LoadYmlTest {
    @Autowired
    private LoadDiskConfig diskConfig;
    @Test
    public void testDisk() {
        String username = diskConfig.getUsername();
        String url = diskConfig.getUrl();
        System.out.println(username);
        System.out.println(url);
    }
}

4.spring加载xml文件

  • 创建一个xml文件:applicationContext.xml,并在其中定义一个bean
  • 通过 ApplicationContext 来加载读取xml文件

不再推介使用 xml 来读取文件了,过于复杂

示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
    <bean id="blog" name="author" class="com.example.commonmybatisplus.entity.UserEntity">
        <property name="id" value="1"/>
        <property name="name" value="ifredom"/>
        <property name="age" value="30"/>
    </bean>
</beans>
@Data
public class UserEntity {
    private Long id;
    private String name;
    private int sex;
    private int age;
}
@SpringBootTest
public class LoadYmlTest {
    @Test
    public void testXml() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserEntity author = context.getBean("author", UserEntity.class);
        System.out.println(author.getName());
    }
}

5.Java基于InputStream读取properties配置文件

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
@SpringBootTest
public class LoadYmlTest {
    @Test
    public void testInputStream() throws IOException {
        Properties properties = new Properties();
        // 使用InPutStream流读取properties文件
        BufferedReader bufferedReader = new BufferedReader(new FileReader("D:/project1.properties"));
        properties.load(bufferedReader);
        // 获取key对应的value值
        String driverClassName = properties.getProperty("driverClassName");
        String username = properties.getProperty("username");
        System.out.println(driverClassName);
        System.out.println(username);
    }
}

到此这篇关于Spring详解四种加载配置项的方法的文章就介绍到这了,更多相关Spring加载配置项内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于springboot activiti 配置项解析

    目录 springboot activiti 配置项 asyncExecutorEnabled属性设置 asyncExecutorActivate 校验流程文件 使用自定义mybatis-mapper 数据源指定 建表规则 检测历史表是否存在 检测身份信息表是否存在 流程部署名称 记录历史等级 spring jpa使用 邮件发送服务配置 自定义流程文件位置 activiti rest 配置 springboot集成activiti基础配置 1.配置Maven 2.配置环境变量 3.配置解析方式,

  • SpringBoot配置项目访问路径URL的根路径方式

    目录 配置项目访问路径URL的根路径 1.SpringBoot在2.0之前版本 2.SpringBoot在2.0之后版本 设置默认访问路径 1.继承WebMvcConfigurerAdapter类或实现WebMvcConfigurer接口 2.@Controller路由设置 配置项目访问路径URL的根路径 1.SpringBoot在2.0之前版本 使用server.context-path server.context-path=/api 2.SpringBoot在2.0之后版本 使用serve

  • 使用springboot logback动态获取application的配置项

    目录 springboot logback动态获取application的配置项 logback自身支持以下方式配置 因此只能使用spring提供的标签来对此参数进行配置 springboot logback配置及动态配置log目录 子节点一 appender 控制台输出appender 文件输入appender root节点-启用配置 动态配置log目录 获取jar目录路径 springboot logback动态获取application的配置项 在多环境的情况下,logback的日志路径需

  • SpringBoot读取properties文件配置项过程解析

    使用SpringBoot开发过程中,难免需要配置相关数据项,然后在Java代码中@Autowired注入并使用. 我们应该如何读取properties文件中的配置项呢? 基于SpringBoot项目,配置项一般都存放在application.properties文件中.有2种常用的方法: 1.使用@Value注解标注在Field上面 2.使用@ConfigurationProperties注解标注在类或者方法上 为了讲解方便,附上application.properties文件配置好的数据项 如

  • springboot如何读取自定义配置项

    我们springboot项目有自己默认的配置文件,一般地由application.yml和bootstrap.yml组成,前者是模块的配置,后者是微服务的配置,后台比前者先被框架加载. 我们有时需要自己定义配置,可能不是简单的字符串,它可能是一个对象,对象里有具体的配置段,它也是application.yml的一部分,你可以把自己的代码添加上,当然你也可以新建全新的文件. 例如,有一个配置由name和version组成,我们在application.yml里可以把它定义成project元素下面的

  • springboot 配置文件配置项前缀为0的数字特殊处理方式

    目录 配置文件配置项前缀为0的数字处理 问题 解决方法 源码类分析 yml配置文件中写以数字0开头的值 记一次springboot踩的坑 配置文件配置项前缀为0的数字处理 问题 spring boot yml配置文件中 ,配置前缀0的数字时,会被特殊处理,如下图配置04100 会当做八进制数处理成2112 解决方法 配置项两边加引号,这时会当做字符串处理 源码类分析 ConstructYamlInt 分析源码可知: 1.以0b开头的数字,会被当做二进制数处理 2.以0x开头的数字,会被当做十六进

  • Spring详解四种加载配置项的方法

    目录 1.spring加载yml文件 2.spring 加载 properties 文件 3.spring加载系统磁盘(properties)文件 4.spring加载xml文件 5.Java基于InputStream读取properties配置文件 本文默认 spring 版本是 spring5 1 spring 加载 yml 文件 2 spring 加载 properties 文件 3 spring 加载 系统磁盘 文件 4 spring 加载 xml 文件 5 Java 基于 InputS

  • 详解JS异步加载的三种方式

    一:同步加载 我们平时使用的最多的一种方式. <script src="http://yourdomain.com/script.js"></script> <script src="http://yourdomain.com/script.js"></script> 同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当当前加载完成,才能进行下一步操作.所以默认同步执行才是安全的.但这样如果js中有输

  • IOS中Json解析实例方法详解(四种方法)

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此"http://www.bejson.com/"网站来进行JSON格式化校验(点击打开链接).此网站不仅可以检测Json代码中的错误,而且可以以视图形式显示json中的数据内容,很是方便. 从IOS5开始,APPLE提供了对json的原生支持(NSJSONSerialization),但是为了兼容以前的iOS版本,可以使用第三方库来解析Json. 本文将介绍Tou

  • 详解Vue3如何加载动态菜单

    目录 1. 整体思路 2. 实现细节 2.1 加载细节 2.2 getInfo 2.3 generateRoutes 1. 整体思路 首先我们来梳理下整体上的实现思路,首先一点:整体思路和 vhr 一模一样. 考虑到有的小伙伴可能已经忘记 vhr 中前端动态菜单的实现思路了,因此本文再和大家分析一下. 为了确保在所有的 .vue 文件中都能访问到到菜单数据,所以选择将菜单数据存入 vuex 中,vuex 是 vue 中一个存储数据的公共地方,所有的 .vue 文件都可以从 vuex 中读取到数据

  • 详解Android布局加载流程源码

    一.首先看布局层次 看这么几张图 我们会发现DecorView里面包裹的内容可能会随着不同的情况而变化,但是在Decor之前的层次关系都是固定的.即Activity包裹PhoneWindow,PhoneWindow包裹DecorView.接下来我们首先看一下三者分别是如何创建的. 二.Activity是如何创建的 首先看到入口类ActivityThread的performLaunchActivity方法: private Activity performLaunchActivity(Activi

  • 详解Android Webview加载网页时发送HTTP头信息

    详解Android Webview加载网页时发送HTTP头信息 当你点击一个超链接进行跳转时,WebView会自动将当前地址作为Referer(引荐)发给服务器,因此很多服务器端程序通过是否包含referer来控制盗链,所以有些时候,直接输入一个网络地址,可能有问题,那么怎么解决盗链控制问题呢,其实在webview加载时加入一个referer就可以了,如何添加呢? 从Android 2.2 (也就是API 8)开始,WebView新增加了一个接口方法,就是为了便于我们加载网页时又想发送其他的HT

  • 详解Qt如何加载libxl库

    使用工具 1.Qt 5.12.3集成开发环境 2.libxl-3.9.4.3(官方下载地址:https://www.libxl.com/download.html) 提示:以下是本篇文章正文内容,下面案例可供参考 一.如何导入libxl库 由于官方给出的教程是MinGW32导入动态库我这边也照着导入libxl的32位动态库,使用MinGW64开发环境同理,如果qt使用的是mvsc环境的朋友可以不用参考此教程 1.pro文件导入静态链接库 1.把lib32.dll文件路径放入到pro文件中: LI

  • 详解react-router4 异步加载路由两种方法

    方法一:我们要借助bundle-loader来实现按需加载. 首先,新建一个bundle.js文件: import React, { Component } from 'react' export default class Bundle extends React.Component { state = { // short for "module" but that's a keyword in js, so "mod" mod: null } componen

  • 详解vue-router数据加载与缓存使用总结

    之前开发了一个单页面应用,按照深度,分为三层:目录页.一级子页(标签页.故事页等).二级子页(故事编辑页). 这三类页面都共享一个完整的数据model,从上级页面进入下一级页面时,能够加载相应数据:回到上一级时,数据有更新.举个栗子,从故事页点击"编辑"按钮,进入故事编辑页则默认填充点击的"编辑"按钮所对应的故事数据:而当在故事编辑页更新数据,返回到故事页时,刚刚更新的信息也能在故事页展示. 对于这项需求,我们需要解决如下几个问题: 三层页面共享数据: 进入或退回当

  • 详解springMVC容器加载源码分析

    springmvc是一个基于servlet容器的轻量灵活的mvc框架,在它整个请求过程中,为了能够灵活定制各种需求,所以提供了一系列的组件完成整个请求的映射,响应等等处理.这里我们来分析下springMVC的源码. 首先,spring提供了一个处理所有请求的servlet,这个servlet实现了servlet的接口,就是DispatcherServlet.把它配置在web.xml中,并且处理我们在整个mvc中需要处理的请求,一般如下配置: <servlet> <servlet-name

随机推荐