Spring Cloud Config 高可用

                           Spring Cloud Config 高可用

高可用配置

当要将配置中心部署到生产环境中时,与服务注册中心一样,我们也希望它是一个高可用的应用。SpringCloudCoiifig实现服务端的高可用非常简单,主要有以下两种方式。

  • 传统模式:不需要为这些服务端做任何额外的配置,只需要遵守一个配置规则,将所有的Config Server都指向同一个Git仓库,这样所有的配置内容就通过统一的共享文件系统来维护。而客户端在指定Config Server位置时,只需要配置Config Server上层的负载均衡设备地址即可,就如下图所示的结构:

  • 服务模式:除了上面这种传统的实现模式之外,我们也可以将Config Server作为一个普通的微服务应用,纳入Eureka的服务治理体系中。这样我们的微服务应用就可以通过配置中心的服务名来获取配置信息,这种方式比起传统的实现模式来说更加有利于维护,因为对于服务端的负载均衡配置和客户端的配置中心指定都通过服务治理机制一并解决了,既实现了高可用,也实现了自维护。由于这部分的实现需要客户端的配合,具体示例读者可详细阅读“客户端详解”一节中的“服务化配置中心”小节 

客户端详解

在学习了关于Spring Cloud Config 服务端的大量配置和使用细节之后,接下来我们将通过下面的内容继续学习Spring Cloud Config客户端的使用与配置。

URI指定配置中心

      Spring Cloud Config 的客户端在启动的时候,默认从工程的classpath中加载配置信息并启动应用,只有当我们配置spring.cloud .config.uri的时候,客户端应用才会尝试连接Spring Cloud Config的服务端来获取远程配置信息并初始化Spring环境配置。同时,我们必须将该参数配置在bootstrap.propertie、环境变量或是其他优先级高于应用Jar包内的配置信息中,才能正确加载到远程配置。若不指定spring.cloud.config.uri参数的话,Spring Cloud Config的客户端会默认尝试连接http://10.0.45.103:8080。

项目github地址:[email protected]:13849141963/spring-cloud.git

【Dalston版】

     在之前的快速入门示例中,我们就是以这种方式实现的,就如下面的配置,其中spring.application.name和spring.cloud.config.profile用于定位配置信息。

spring.application.name=springcloud-config-client
# 指明远程仓库的分支
spring.cloud.config.label=master
# dev开发环境配置文件   test测试环境    pro正式环境
spring.cloud.config.profile=dev
# 配置中心config-server的地址
#spring.cloud.config.uri=http://10.0.45.103:8080/

服务化配置中心

在前几篇博客中,我们己经学会了如何构建服务注册中心、如何发现与注册服务。那么Config Server是否也能以服务的方式注册到服务中心,并被其他应用所发现来实现配置信息的获取呢?答案是肯定的。在Spring Cloud中,我们也可以把Config Server视为微服务架构中与其他业务服务一样的一个基本单元。
下面,我们就来详细介绍如何将Config Server注册到服务中心,并通过服务发现来访问Config Server并获取Git仓库中的配置信息。下面的内容将基于快速入门中实现的 springcloud-config-server和springcloud-config-client工程来进行改造实现。
服务端配置
1、在springcloud-config-server 的 pom.xml 中增加spring-cloud-starter-eureka,spring-cloud-config-server依赖,以实现将分布式配置中心加入Eureka的服务治理体系。

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--分布式配置中心-->
    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-config-server</artifactId>
   </dependency>

   <!--Eureka服务注册中心-->
   <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
   </dependency>

   <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.RC1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
   </dependencyManagement>

 2、在application.properties配置文件中配置参数eureka.client.service-url.defaultZone已指定服务注册中心的位置,详细内容如下:

spring.application.name=springcloud-config-server
server.port=8080
# 配置git仓库地址
spring.cloud.config.server.git.uri=https://github.com/13849141963/spring-config-file/
# 配置仓库的分支
spring.cloud.config.label=master
# 配置仓库路下的相对搜索位置.可以配置多个
spring.cloud.config.server.git.search-paths=respoitory
# 访问git仓库的用户名
spring.cloud.config.server.git.username=13849141963
# 访问git仓库的用户密码 如果Git仓库为公开仓库,可以不填写用户名和密码,如果是私有仓库需要填写
spring.cloud.config.server.git.password=********
#将分布式配置中心交给eureka集群注册中心来管理
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/,http://peer3:3333/eureka/,http://peer2:2222/eureka/
#虽然SpringCloudConfig提供这样的功能,但是为了支持更好的内容管理和版本控制等强大功能,还是推荐使用Git仓库的方式
#不使用git仓库或者svn仓库的存储方式   configSever会默认从应用的src/main/resources目录下搜寻文件
#spring.profiles.active=native
#如果需要指定搜索配置文件的路径,通过这个属性来指定具体的配置文件位置
#spring.cloud.config.server.native.search-locations=文件位置

3、在应用主类中,新增@EnableDiscoveryClient注解,用来将springcloud-config-server应用注册到上面的服务注册中心上去。

//分布式配置中心注解
@EnableConfigServer
//发现注册中心
@EnableEurekaClient
@SpringBootApplication
public class SpringcloudConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudConfigServerApplication.class, args);
    }
}

 4、启动该应用,并访问eureka集群http://10.0.45.103:1111,http://10.0.45.103:2222,http://10.0.45.103:3333,可以在Eureka Server的信息面板中看到springcloud-config-server已经被注册了。

客户端配置

1、在springcloud-config-client的pom.xml中新增spring-cloud-starter-eureka依赖,以实现客户端发现springcloud-config-server服务,具体配置如下:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--分布式配置中心-->
    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

    <!--Eureka服务注册中心-->
    <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

   <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.RC1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、在bootstrap.properties文件中,按如下配置:

spring.application.name=springcloud-config-client
# 指明远程仓库的分支
spring.cloud.config.label=master
# dev开发环境配置文件   test测试环境    pro正式环境
spring.cloud.config.profile=dev
# 配置中心config-server的地址 在configServer分布式配置中心没有在eureka注册中心注册时,指定该ConfigServer的服务器地址通过访问Controller
# 来测试客户端获取git仓库的某个文件内容,之后ConfigServer在注册中心进行注册就可以使用service-id属性来指定分布式服务的名称,直接使用分布式服务
#spring.cloud.config.uri=http://10.0.45.103:8080/
#端口
server.port=7001
#开启通过服务来访问ConfigServer的功能
spring.cloud.config.discovery.enabled=true
#指定分布式配置中心服务名称
spring.cloud.config.discovery.service-id=springcloud-config-server
#将分布式配置中心交给eureka集群注册中心来管理
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/,http://peer3:3333/eureka/,http://peer2:2222/eureka/
#关闭刷新安全认证
management.security.enabled=false
#和重试机制相关的配置有如下四个:
# 配置重试次数,默认为6
spring.cloud.config.retry.max-attempts=6
# 间隔乘数,默认1.1
spring.cloud.config.retry.multiplier=1.1
# 初始重试间隔时间,默认1000ms
spring.cloud.config.retry.initial-interval=1000
# 最大间隔时间,默认2000ms
spring.cloud.config.retry.max-interval=2000

 其中,通过eureka.client.service-url.defaultZone参数指定服务注册中心,用于服务注册与发现;在将spring.cloud.config.discovery.enabled参数设置为true,开启通过服务来访问Config Server的功能;最后利用spring.cloud.config.discovery.serviceId参数来指定Config Server注册的服务名。这里的spring.application.name和spring.cloud.config.profile如之前通过URI的方式访问的时候一样,用来定位Git中的资源。

3、在应用主类中,增加@EnableEurekaClient注解,用来发现springcloud-config-server服务,利用其来加载应用配置:

@SpringBootApplication
@EnableEurekaClient
public class SpringcloudConfigClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudConfigClientApplication.class, args);
    }
}

4、沿用之前我们创建的Controller来加载Git中的配置信息:

@RestController
public class TestGetConfigController {

    @Value("${configFile}")
    String configFile;

    @RequestMapping(value = "/configFile")
    public String getConfigFile(){
        return configFile;
    }
}

5、完成上述配置之后,我们启动客户端应用。若启动成功,访问http://10.0.45.103:7001/configFile,可以在Eureka Server的信息面板中看到该应用已经被注册成功。

6、访问客户端应用提供的服务 http://10.0.45.103:7001/configFile,此时,我们会返回在Git仓库中application-dev.properties文件中的配置config-filede属性内容:“configFile dev version 1”

失败快速响应与重试

Spring Cloud Config的客户端会预先加载很多其他信息,然后再开始连接Config Serve进行属性的注入。当我们构建的应用较为复杂的时候,可能在连接Config Server之前花较长的启动时间,而在一些特殊场景下,我们又希望可以快速知道当前应用是否能顺利从Config Server获取到配置信息,这对在初期构建调试环境时,可以减少很多等待启动的时间。要实现客户端优先判断Config Server获取是否正常,并快速响应失败内容,只需在bootstrap.properties中配置参数spring.cloud.config.failFast=true即可。

       我们可以实现一下,在未配置该参数前,不启动Config Server,直接启动客户端应用,可以获得下面的报错信息。同时,在报错之前,可以看到客户端应用加载了很多内容,比如说Controller的请求等。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testGetConfigController': Injection of autowired dependencies failed;

 加上spring.cloud.config.fail-fast=true 参数之后,在启动客户端应用,可以获取下面的报错信息,并且前置的加载内容少了很多,这样通过该参数有效地避免的了当Congfig Server配置有误时,不需要多等待前置的一些加载时间,实现了快速返回失败信息

java.lang.IllegalStateException: Could not locate PropertySource and the fail fast property is set, failing

 上面我们演示了当Config Server宕机或是客户端配置不正确导致连接不到而启动失败的情况,快速响应的配置可以发挥比较好的效果。但是,若只是因为网络波动等其他间接性原因导致的问题,直接启动失败似乎代价有点高。所以Config客户端还提供了自动重试的功能,在开启重试功能前,先确保已经配置了spring.cloud.config.failFast=true,在进行下面的操作。

1、在客户端的pom.xml中增加spring-retry和spring-boot-starter-aop依赖,具体如下:

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

 2、不需要在做其他任何配置,启动客户端应用,在控制台中可以看到如下内容。客户端在连接Config Server失败之后,会继续尝试,知道第六次失败后才返回错误信息。通过这样的重试机制,可以避免一些间歇性问题引起的失败导致客户端应用无法启动的情况。

2018-11-06 14:14:50.752  INFO 828 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2018-11-06 14:14:52.813  INFO 828 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2018-11-06 14:14:54.947  INFO 828 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2018-11-06 14:14:57.188  INFO 828 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2018-11-06 14:14:59.548  INFO 828 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2018-11-06 14:15:02.044  INFO 828 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2018-11-06 14:15:03.084 ERROR 828 --- [           main] o.s.boot.SpringApplication               : Application startup failed
java.lang.IllegalStateException: Could not locate PropertySource and the fail fast property is set, failing

若对默认的最大重试次数和重试间隔等设置不满意,还可以通过下面的参数进行调整。

spring.cloud.config.retry.multiplier:初始重试间隔时间(单位为毫秒),默认为1000毫秒。
spring.cloud.config.retry.initial-interval:下一间隔的乘数,默认为1.1所以当初间隔是1000毫秒时,下一次失败的间隔为1100毫秒。
spring.cloud.config.retry.max-interval:最大间隔时间,默认为2000毫秒。
spring.cloud.config.retry.max.attempts:最大重试次数,默认为六次。

获取远程配置

       在入门示例中,我们队{application}、{profile}、{lable}这些参数已经有了一定的了解。在Git仓库中,一个形如{application}-{profile}.properties或{application}-{profile}.yml的配置文件,通过URL请求和客户端配置的访问对应可以总结如下:

1、通过向Config Server发送GET请求以直接的方式获取,可用下面的链接形式。 

 不带{label}分支信息,默认访问master分支,可使用:
   1./{application}-{profile}.yml
   2./{application}-{profile}-properties
 带{label}分支信息,可使用:
   1./{label}/{application}-{profile}.yml
   2./{application}/{profile}[/{label}]
   3./{label}/{application}-{profile}.properties

2、通过客户端配置方式加载的内容如下所示。

 1.spring• application.name:对应配置文件中的{application}内容。
 2.spring. cloud, config.profile:对应配置文件中{profile}内容。
 3.spring.cloud.config. label:对应分支内容,如不配置,默认为master。

动态刷新配置

       有时候,我们需要对配置内容做一些实时更新,那么Spring Cloud Config是否可以实现呢?答案显然是可以的。下面,我们以快速入门中的示例作为基础,看看如何进行改造来实现配置内容的实时更新。
       首先,回顾一下,当前我们已经实现了哪些内容。
       1、config-repo:定义在 Git仓库中的一个目录,其中存储了应用名为didispace的多环境配置文件,配置文件中有一个from参数。

       2、 config-server:配置了 Git仓库的服务端。
       3、config- client:指定了springcloud-config-server为配置中心的客户端,应用名为springcloud-config-client,用来访问配置服务器以获取配置信息。该应用中提供了一个/configFile接口,它会获取 respository/ application-dev.properties 中的 configFile属性返回。
       在改造程序之前,我们先将 springcloud-config- server 和 springcloud-config-client 都启动起来,并访问客户端提供的REST接口 http:// localhost:7002/ configFile 来获取配置信息,获得的返回内容为 configFile dev version 1。接着,我们可以尝试使用Git工具修改当前配置的内容,比如, 将 respository/application-dev.properties 中的 configFile 的值从 configFile = configFile dev version 1 修改为 configFile = configFile dev version 2,再访问 http://10.0.45.103:7001/configFile,可以看到其返回内容还是configFile dev version 1。

       接下来,我们将在springcloud-config-client端做一些改造以实现配置信息的动态刷新。

 1、在springcloud-config-client的pom.xml中新增 spring-boot-starter-actuator 监控模块。其中包含了/refresh端点的实现,该端点将用于应用配置信息的重新获取与刷新。

  <!--实时刷新配置文件-->
  <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-actuator</artifactId>
  </dependency>

2、重新启动 springcloud-config-client,访问一次 http://10.0.45.103:7001/configFile 可以看到当前的配置值。

3、修改Git 仓库 respository/application-dev.properties文件中的值。

4、在访问一次 http://10.0.45.103:7001/configFile ,可以看到配置值没有发生改变。

5、通过POST请求发送到 http://10.0.45.103:7001/refresh,我们可以看到返回内容如下,代表configFile参数的配置内容被更新了:

6、再一次访问 http://10.0.45.103:7001/configFile,可以看到配置值已经是更新后的值了。

通过上面的介绍,大家不难想到,该功能还可以同Git仓库的Web Hook功能进行关联,当有Git提交变化时,就给对应的配置主机发送/refresh请求来实现配置信息的实时更新。但是,当我们的系统发展壮大之后,维护这样的刷新清单也将成为一个非常大的负担,而且很容易犯错,那么有什么办法可以解决这个复杂度呢?后续我们将介绍如何通过 Spring Cloud Bus来实现以消息总线的方式进行配置变更的通知,并完成集群上的批量配置更新。

远程拉取配置文件操作数据库

我们在项目实战中肯定不会像上面的操作一样,我们会把一些常用的配置信息放在github的配置文件中,放入多个环境的配置文件,每个配置文件中会有一些mysql,mybatis,redis,分页,等诸多的配置信息参数,下面我们就来演示从github获取mysql,mybatis的相关配置信息来操作数据库.

1、准备好配置文件的相关信息

#mysql相关配置信息
spring.datasource.url=jdbc:mysql://10.0.45.103/mysql-test?characterEncoding=utf8
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.initialSize=5
spring.datasource.maxActive=200
spring.datasource.minIdle=5
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=select 'x'
spring.datasource.testWhileIdle=true
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxOpenPreparedStatements=20
spring.datasource.testOnBorrow=false

#mybatis相关配置信息
mybatis.mapper-locations=com/zy/cn/mapper/*.xml
mybatis.type-aliases-package=com.zy.cn.entity

2、启动eureka集群项目[上一篇博文中有搭建过程,代码已上传github]

3、启动springcloud-config-server项目[代码已上传github]

4、在客户端建立bootstrap.properties文件,在启动入口类时会首先加载bootstrap.properties中的相关配置信息参数如下:

spring.application.name=springcloud-config-client
# 对应的文件为application-datasource.properties文件
spring.cloud.config.profile=datasource
# 指明远程仓库的分支
spring.cloud.config.label=master
# 配置中心config-server的地址 在configServer分布式配置中心没有在eureka注册中心注册时,指定该ConfigServer的服务器地址通过访问Controller
# 来测试客户端获取git仓库的某个文件内容,之后ConfigServer在注册中心进行注册就可以使用service-id属性来指定分布式服务的名称,直接使用分布式服务
#spring.cloud.config.uri=http://10.0.45.103:8080/
#端口
server.port=7001
#开启通过服务来访问ConfigServer的功能
spring.cloud.config.discovery.enabled=true
#指定分布式配置中心服务名称
spring.cloud.config.discovery.service-id=springcloud-config-server
#将分布式配置中心交给eureka集群注册中心来管理
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/,http://peer3:3333/eureka/,http://peer2:2222/eureka/
#启动失败时能够快速响应
spring.cloud.config.fail-fast=true
#关闭刷新安全认证
management.security.enabled=false
#和重试机制相关的配置有如下四个:
# 配置重试次数,默认为6
spring.cloud.config.retry.max-attempts=6
# 间隔乘数,默认1.1
spring.cloud.config.retry.multiplier=1.1
# 初始重试间隔时间,默认1000ms
spring.cloud.config.retry.initial-interval=1000
# 最大间隔时间,默认2000ms
spring.cloud.config.retry.max-interval=2000

5、创建DataSourceProperties.class 作用就是通过@ConfigurationProperties注解实现了配置信息的注入,该注解的作用:当以@ConfigurationProperties这种方式注册bean时,该bean具有常规名称:<prefix>-<fqn>,属性  //其中<prefix>是在@ConfigurationProperties注释中指定的环境[系统环境]键前缀,并且<fqn>是bean的完全限定名称。 //如果注释没有提供任何前缀,则只使用bean的完全限定名称。系统环境就是已经加载bootstrap.properties文件从远程github仓库获取相关信息通过@ConfigurationProperties 注解给DataSourceProperties的属性进行参数绑定。

/**
 * 该类配置数据源相关属性
 * 从springcloud config远程github获取配置文件信息
 */
//https://www.breakyizhan.com/springboot/3287.html Springboot中文文档24.7
//当以@ConfigurationProperties这种方式注册bean时,该bean具有常规名称:<prefix>-<fqn>,睡醒
//其中<prefix>是在@ConfigurationProperties注释中指定的环境[系统环境]键前缀,并且<fqn>是bean的完全限定名称。
//如果注释没有提供任何前缀,则只使用bean的完全限定名称。
//通过使用@ConfigurationProperties注解实现了配置信息的注入;
// 然后又通过使用@EnableConfigurationProperties注解才使得配置bean被创建出来
@ConfigurationProperties(prefix = DataSourceProperties.PREFIX, ignoreUnknownFields = false)
public class DataSourceProperties {

    public DataSourceProperties() {
        super();
    }
    //定义前缀    //对应远程配置文件里的key
    public final static String PREFIX = "spring.datasource";

    private String type;
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private int maxActive = 1000;
    private int maxIdle = 100;
    private int minIdle = 8;
    private int initialSize = 10;
    private int maxWait;
    private int timeBetweenEvictionRunsMillis;
    private int minEvictableIdleTimeMillis;
    private String validationQuery;
    private boolean testWhileIdle;
    private boolean poolPreparedStatements;
    private int maxOpenPreparedStatements;
    private boolean testOnBorrow = true;
    private boolean testOnReturn = false;

    //提供get/set方法
}

6、创建MybatisSourceProperties.class文件

//@ConfigurationProperties 标注的“已经存在”的 bean 都会从系统环境中加载配置信息
@ConfigurationProperties(prefix = MybatisSourceProperties.PREFIX, ignoreUnknownFields = false)
//通过使用@ConfigurationProperties注解实现了配置信息的注入;
// 然后又通过使用@EnableConfigurationProperties注解才使得配置bean被创建出来
public class MybatisSourceProperties {

    //指定远程配置文件前缀
    public final static String PREFIX = "mybatis";
    //mapper配置文件位置
    private String mapperLocations;
    //实体的别名
    private String typeAliasesPackage;
    
    //并提供get/set方法
}

7、在入口类上该注解上加参数 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}),意思就是将spring boot自带的DataSourceAutoConfiguration禁掉,防止自动配置数据源

@MapperScan("com.zy.cn.dao")
@EnableEurekaClient
//将spring boot自带的DataSourceAutoConfiguration禁掉,防止自动配置数据源
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SpringcloudProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringcloudProviderApplication.class, args);
    }
}

8、自定义数据源 MybatisDataSource.class文件 ,该文件中创建数据源组件,创建SqlSessionFactory,创建事物管理器,在这里注意:通过使用@ConfigurationProperties注解实现了配置信息的注入,然后又通过使用@EnableConfigurationProperties注解才使得配置bean被创建出来。

@Configuration
@MapperScan("com.zy.cn.*")
//加载数据源以及mybatis的相关配置信息
@EnableConfigurationProperties({DataSourceProperties.class,MybatisSourceProperties.class})
//通过使用@ConfigurationProperties注解实现了配置信息的注入;
// 然后又通过使用@EnableConfigurationProperties注解才使得配置bean被创建出来
@EnableTransactionManagement//事务管理器
public class MybatisDataSource {

    @Autowired
    private  DataSourceProperties dataSourceProperties;

    @Autowired
    private MybatisSourceProperties mybatisSourceProperties;

    private DruidDataSource datasource = null;

    //创建数据源组件
    @Bean(destroyMethod = "close")
    public DataSource dataSource(){
        datasource = new DruidDataSource();
        //注入连接数据库的·url地址
        datasource.setUrl(dataSourceProperties.getUrl());
        //注入类型
        datasource.setDbType(dataSourceProperties.getType());
        datasource.setDriverClassName(dataSourceProperties.getDriverClassName());
        //注入用户名密码
        datasource.setUsername(dataSourceProperties.getUsername());
        datasource.setPassword(dataSourceProperties.getPassword());
        //连接相关配置参数
        datasource.setInitialSize(dataSourceProperties.getInitialSize());
        datasource.setMaxActive(dataSourceProperties.getMaxActive());
        datasource.setMinIdle(dataSourceProperties.getMinIdle());
        datasource.setMaxWait(dataSourceProperties.getMaxWait());
        datasource.setTimeBetweenEvictionRunsMillis(dataSourceProperties.getTimeBetweenEvictionRunsMillis());
        datasource.setValidationQuery(dataSourceProperties.getValidationQuery());
        datasource.setTestWhileIdle(dataSourceProperties.getTestWhileIdle());
        datasource.setTestOnReturn(dataSourceProperties.isTestOnReturn());
        datasource.setTestOnBorrow(dataSourceProperties.isTestOnBorrow());
        datasource.setPoolPreparedStatements(dataSourceProperties.getPoolPreparedStatements());
        datasource.setMaxOpenPreparedStatements(dataSourceProperties.getMaxOpenPreparedStatements());
        return datasource;
    }

    @PreDestroy
    public void close() {
        if(datasource != null){
            //关闭数据源
            datasource.close();
        }
    }

    //创建sqlSessionFactory连接对象
    @Bean
    public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //注入数据源组件
        sqlSessionFactoryBean.setDataSource(dataSource());
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        //mybatis的mapper配置文件位置
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mybatisSourceProperties.getMapperLocations()));
        //指定实体别名的位置
        sqlSessionFactoryBean.setTypeAliasesPackage(mybatisSourceProperties.getTypeAliasesPackage());
        return sqlSessionFactoryBean.getObject();
    }

    //创建事务管理器
    @Bean
    public PlatformTransactionManager transactionManager() {
        //注入数据源对象
        return new DataSourceTransactionManager(dataSource());
    }
}

 9.创建mapper配置文件

10.进行测试,测试成功说明从github远端获取配置信息进行加载从而进行操作数据库。这样子也是方便对各个环境的尽快地做出改变不需要人为的进行管理。

猜你喜欢

转载自blog.csdn.net/weixin_40470497/article/details/83780709