【java学习】Spring配置文件、配置中心

java编程有一条不成文的规定就是:“约定大于配置,配置大于代码”,从而解耦。

1,配置文件

在Spring Boot项目中,把很多配置信息写入配置文件(properties或者yml文件),但每次修改配置后必须重启服务。
不管yml文件还是properties文件,都接受spring样式占位符$ {...}来写入环境变量。

1)YAML文件

  1. 文件后缀为 .yml
    bootstrap.ymlapplication.yml ,同一目录下:bootstrap.yml 先加载 application.yml后加载;
    文件名可自定义,要在项目启动时指定配置文件的名字。
  2. 基本语法
    大小写敏感;
    使用缩进(tab,相同层级的元素左对齐)表示层级关系;
    '#'表示注释。
  3. 同时存在yml和propertries文件,前者优先级更高。

1>支持数据类型

  1. 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
keytype: 
    child-key: value
    child-key2: value2
  1. 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
stages:
  # 静态检查
  - pre_verify
  # 项目构建
  - build
  # 运行时检查
  - verify
  # 自动化测试
  - auto_test
  # 部署
  - deploy
  # 测试
  - test
  # 发布
  - release
  1. 纯量(scalars):单个的、不可再分的值
boolean: 
    - TRUE  #true,True都可以
    - FALSE  #false,False都可以
float:
    - 3.14
    - 6.8523015e+5  #可以使用科学计数法
int:
    - 123
    - 0b1010_0111_0100_1010_1110    #二进制表示
null:
    nodeName: 'node'
    parent: ~  #使用~表示null
string:
    - 哈哈
    - 'Hello world'  #可以使用双引号或者单引号包裹特殊字符
    - newline
      newline2    #字符串可以拆成多行,每一行会被转化成一个空格
date:
    - 2018-02-17    #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime: 
    -  2018-02-17T15:02:31+08:00    #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区

2>引用

& 锚点和 * 别名,可以用来引用:

# & 用来建立锚点(defaults)
defaults: &defaults
  adapter:  postgres
  host:     localhost

development:
  database: myapp_development
  # << 表示合并到当前数据,* 用来引用锚点
  <<: *defaults

test:
  database: myapp_test
  <<: *defaults
defaults:
  adapter:  postgres
  host:     localhost

development:
  database: myapp_development
  adapter:  postgres
  host:     localhost

test:
  database: myapp_test
  adapter:  postgres
  host:     localhost

3>项目位置及优先级

首先application.yaml在Spring Boot中可以写在四个不同的位置,优先级依次降低(相同属性高优先级覆盖低优先级):

  1. 项目根目录下的config目录中
  2. 项目根目录下
  3. classpath下的config目录中
  4. classpath目录下

启动加载配置有3种方式:

java -jar myproject.jar --spring.config.name=app  4个位置里的配置文件名
或者  spring.config.location   这种定义方式会覆盖掉默认的四个位置
或者  spring.config.additional-location  表示在四个位置的基础上,再添加几个位置,新添加的位置的优先级大于原本的位置

4>java读取yaml数据

  1. 对象
    yaml见上文举例;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.HashMap;

@Component
//把环境变量中以mkeytype打头的属性都绑定到类的成员变量上,并完成对应类型的转换
@ConfigurationProperties(prefix = "mkeytype")
public class KeyTypeMap extends HashMap<String, String> {
}

通过ApplicationContextAware接口加载对应的bean

KeyTypeMap keyTypeMap = SpringContextUtils.getBean(KeyTypeMap.class);
  1. 数组
redis:	
  redisConfigs:	
    - host: 192.168.66.128	
      port: 6379	
    - host: 192.168.66.129	
      port: 6380
@Component	
@ConfigurationProperties(prefix = "redis")	
public class RedisCluster {	
    private List<SingleRedisConfig> redisConfigs;	
    //省略getter/setter	
}
  1. 单值
    通过 @Value("${spring.application.name}")获取。

2)properties文件

String driver="com.mysql.jdbc.Driver";//mysql提供的Driver接口的实现类
String jdbcUrl="jdbc:mysql:///user";//此处为"jdbc:mysql://localhost:3306/user"的简化形式,user为数据库名
String user="root";
String password="451535";
Class.forName(driver);//通过反射动态实例化mysql数据库驱动类
Connection conn= DriverManager.getConnection(jdbcUrl,user,password);

  1. 文件后缀为“.properties”,属文本文件;
  2. 内容格式:“键=值”
  3. 无序
  4. “#”作为注释
  5. 场景:将配置文件(如数据库密码)等与java代码解耦。
  6. 通过java.util.Properties可以读取或者输出Properties文件

2,配置中心

  1. 远程配置内容与本地配置内容重叠时,以远程配置内容为准;

1)优点

  1. 统一管理配置;
  2. 修改配置后不需要手动打包;
  3. 修改配置后不需要重启服务。

2)常用组件

在Spring Cloud中,Spring Cloud Config是最早的配置中心,目前有一些用的比较多的开源的配置中心,比如携程的 Apollo、蚂蚁金服的 disconf 等,对比 Spring Cloud Config,这些配置中心功能更加强大。

3)Spring Cloud Config三大组件

1>config-server

提供给客户端获取配置。

2>Git

用于存储和修改配置。除了 git 外,还可以用数据库、svn、本地文件等作为存储。

3>Spring Cloud Bus

通知客户端配置变更。

4)demo

1)config bootstrap.yml 文件

git存储配置:

spring:
  application:
    name: config-server  # 应用名称
  cloud:
     config:
        server:
          git:
            uri: https://github.com/config-demo #配置文件所在仓库
            username: github 登录账号
            password: github 登录密码
            default-label: master #配置文件分支
            search-paths: config  #配置文件所在根目录

数据库存储配置:

spring:
  application:
    name: config-server 
  profiles:
    active: jdbc
  cloud:
    config:
      server:
        jdbc:
          sql: SELECT KEY, VALUE from CONFIG_INFO where LABEL=?
          order: 0
        default-label: master
  security:
    #配置后每次访问config-server 都需要验证
    user:
      name: root
      password: security密码

2>在 Application 启动类上注解 @EnableConfigServer

@SpringBootApplication
@EnableConfigServer
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

maven依赖:

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

<!-- spring cloud config 服务端包 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

3>通过浏览器访问配置中心

ip和port为config-service对应的ip和端口。
查询链接: ip:port/查询规则
如:上文中数据库的查询,通过链接10.3.3.3:8888/master可以返回所有满足要求的查询(config_info表中label为mater的结果)。

4>使用配置

  1. maven依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- spring cloud config 客户端包 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  1. bootstrap.yml
spring:
  profiles: dev
  application:
    name: config-single-client
  cloud:
     config:
       uri: http://localhost:3301
       label: master
       profile: dev
       #设为true,如果无法连接config service,启动时会抛异常,并停止服务
       fail-fast: true
  1. 读取配置
    要读取配置中心的内容,需要增加相关的配置类,Spring Cloud Config 读取配置中心内容的方式和读取本地配置文件中的配置是一模一样的。可以通过 @Value 或 @ConfigurationProperties 来获取。
    区别在于@ConfigurationProperties 配合下文的@RefreshScope可以自动刷新配置信息,但是@Value不可以,所以不推荐使用@Value。
@Data
@Component
public class GitConfig {

    @Value("${data.env}")
    private String env;

    @Value("${data.user.username}")
    private String username;

或者:
    private String psw;

    @Value("${data.user.password:abc}")
	  public void setPsd(String psw){
	  		this.psw= psw;
	  }
}

或者:

@Component
@Data
@ConfigurationProperties(prefix = "data")
public class GitAutoRefreshConfig {

    public static class UserInfo {
        private String username;

        private String password;

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        @Override
        public String toString() {
            return "UserInfo{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }

    private String env;

    private UserInfo user;
}
  1. 实现自动刷新配置
    spring-cloud-config提供了一个刷新机制,但是需要我们主动触发。那就是 @RefreshScope 注解并结合 actuator ,注意要引入 spring-boot-starter-actuator 包。

yml中增加,然后在需要读取配置的类上增加 @RefreshScope 注解。

management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

我们提供一个接口,每次调用这个接口就可以自动刷新配置信息。

@GetMapping(value = "autoShow")
    public Object autoShow(){
        return gitAutoRefreshConfig;
    }

但其实每次修改配置后都需要主动调用这个接口,git提供了webhook的方式,当有代码变更的时候,会调用我们设置的地址,从而达到自动刷新的目的。如果端比较多,webhook需要一个个调用刷新配置,此时使用Spring Cloud Bus的广播功能,让client端都订阅配置更新事件,以此批量更新。

5>结合Eureka

Spring Cloud Config 注册到 Eureka 之上,方便其他服务消费者使用,并且可以注册多个配置中心服务端,以实现高可用。
config-service只需要把自己注册到Eureka即可。
config客户端同样需要先注册到Eureka,修改配置信息:

spring:
  application:
    name: test-service
  cloud:
    config:
      discovery:
        enabled: true
        #指定配置中心服务端的server-id 
        service-id: config-service
      #设为true,如果无法连接config server,启动时会抛异常,并停止服务
      fail-fast: true
      username: root
      password: security密码
      profile: dev
      label: master
      retry:
        initial-interval: 1000
        multiplier: 1.3
        max-attempts: 6
        max-interval: 3000
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值