前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第三十八章:基于SpringBoot架构使用Profile完成打包环境分离

第三十八章:基于SpringBoot架构使用Profile完成打包环境分离

作者头像
恒宇少年
发布2018-06-27 16:21:49
5790
发布2018-06-27 16:21:49
举报

在中大型企业项目开发中,环境分离是必不可少的一步,然而现在的开发人员也只是有这个概念,还是有很多项目采用普通的方式,每次打包发布部署的时候改动一大堆的配置文件,有一个地方忘记改就相当于白更新了一次系统,这种修改配置文件完成环境更换的方式给我们带来了很多的困扰,浪费了我们很多宝贵的时间!早在Spring 3.1版本就已经为我们提供了环境分离的相关注解配置方式,不过在传统的Spring项目中配置Profile确实有点麻烦,在Spring版本的不断更新直到后来SpringBoot成长起来后Profile已经能够很好支持项目配置环境分离。

本章目标

基于SpringBoot平台完成简单的数据库环境操作分离,根据激活不同的Profile完成不同的数据库操作。

SpringBoot 企业级核心技术学习专题

专题

专题名称

专题描述

001

Spring Boot 核心技术

讲解SpringBoot一些企业级层面的核心组件

002

Spring Boot 核心技术章节源码

Spring Boot 核心技术简书每一篇文章码云对应源码

003

Spring Cloud 核心技术

对Spring Cloud核心技术全面讲解

004

Spring Cloud 核心技术章节源码

Spring Cloud 核心技术简书每一篇文章对应源码

005

QueryDSL 核心技术

全面讲解QueryDSL核心技术以及基于SpringBoot整合SpringDataJPA

006

SpringDataJPA 核心技术

全面讲解SpringDataJPA核心技术

构建项目

使用Idea工具创建一个SpringBoot项目,目前SpringBoot的版本已经更新至1.5.8,我们采用最新版本来完成本章内容,添加相关JPAMySQLDruidLombokWebFastJson等,pom.xml依赖相关配置如下所示:

代码语言:javascript
复制
....省略部分配置
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

        <!--引入druid最新maven依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.39</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
....省略部分配置

配置数据库

我们创建三个数据库分别是project_prod => 线上环境数据库、project_dev=>开发环境数据库、project_beta=>线上测试环境数据库,这样我们在切换Profile时可以很好的区分环境,下面我们创建一张用户基本信息表,SQL如下:

代码语言:javascript
复制
-- ----------------------------
-- Table structure for system_user_info
-- ----------------------------
DROP TABLE IF EXISTS `system_user_info`;
CREATE TABLE `system_user_info` (
  `SUI_ID` int(11) NOT NULL AUTO_INCREMENT,
  `SUI_NICK_NAME` varchar(50) DEFAULT NULL,
  `SUI_LOGIN_NAME` varchar(30) DEFAULT NULL,
  `SUI_LOGIN_PASSWORD` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`SUI_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

将上面SQL分别在三个数据库内分别执行一次,保证我们数据结构环境一致,然后对应数据库分别插入数据,如下:

代码语言:javascript
复制
INSERT INTO `system_user_info` VALUES ('1', '线上测试环境用户', 'beta', 'beta_password');
INSERT INTO `system_user_info` VALUES ('1', '开发环境用户', 'dev', 'dev_password');
INSERT INTO `system_user_info` VALUES ('1', '正式环境用户', 'prod', 'prod_password');

这样我们就可以区分项目正在访问的具体环境。

创建Entity

对应system_user_info数据表创建一个数据实体,如下所示:

代码语言:javascript
复制
package com.yuqiyu.chapter38.entity;

import lombok.Data;

import javax.persistence.*;

/**
 * 用户基本信息实体
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/10/29
 * Time:08:25
 * 码云:http://git.oschina.net/jnyqy
 * ========================
 */
@Entity
@Table(name = "system_user_info")
@Data
public class SystemUserInfoEntity
{
    /**
     * 主键
     */
    @Column(name = "SUI_ID")
    @GeneratedValue
    @Id
    private Integer id;
    /**
     * 昵称
     */
    @Column(name = "SUI_NICK_NAME")
    private String nickName;
    /**
     * 登录名
     */
    @Column(name = "SUI_LOGIN_NAME")
    private String loginName;
    /**
     * 登录密码
     */
    @Column(name = "SUI_LOGIN_PASSWORD")
    private String loginPassword;
}

接下来我们为上面的实体创建一个JPA接口,继承JpaRepository<T,PK>接口完成Jpa扫描自动代理实例的动作。

创建JPA

SystemUserInfoJPA接口内容如下所示:

代码语言:javascript
复制
package com.yuqiyu.chapter38.jpa;

import com.yuqiyu.chapter38.entity.SystemUserInfoEntity;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * 系统用户信息jpa
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/10/29
 * Time:08:30
 * 码云:http://git.oschina.net/jnyqy
 * ========================
 */
public interface SystemUserInfoJPA
    extends JpaRepository<SystemUserInfoEntity,Integer>
{

}

配置Profile环境

SpringBoot内已经为了约定好了Profile配置文件的命名规则,即:application-xxx.properties或者application-xxx.yml,我们只需要将对应环境的配置文件放到resources目录下即可,也就是classpath下,我们对应我们的数据库环境编写三个不同的配置文件。

application-dev.yml

根据我们与SpringBoot的约定在application-dev.xml配置文件内配置的都是开发环境信息,里面包含了开发环境数据源配置信息,当然在实际的项目开发过程中配置信息可以任意约定。配置内容如下所示:

代码语言:javascript
复制
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/project_dev?characterEncoding=utf8
    username: root
    password: 123456
    #最大活跃数
    maxActive: 20
    #初始化数量
    initialSize: 1
    #最大连接等待超时时间
    maxWait: 60000
    #打开PSCache,并且指定每个连接PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    #通过connectionProperties属性来打开mergeSql功能;慢SQL记录
    #connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 1 from dual
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    #配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
    filters: stat, wall, log4j
  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true

在上面代码中可以看到,我们连接了本地的project_dev数据库来作为开发环境的访问数据源。

application-beta.yml

application-beta.yml配置文件就是我们与SpringBoot约定的线上测试环境,在我们实际的开发过程中线上测试环境肯定与开发环境不是同一个数据库,这时我们将application-dev.yml配置文件复制一份,修改下数据库链接信息即可,如果你的application-beta.yml还存在其他的配置,不要忘记修改成相关的环境配置。配置信息如下所示:

代码语言:javascript
复制
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/project_beta?characterEncoding=utf8
    username: root
    password: 123456
    #最大活跃数
    maxActive: 20
    #初始化数量
    initialSize: 1
    #最大连接等待超时时间
    maxWait: 60000
    #打开PSCache,并且指定每个连接PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    #通过connectionProperties属性来打开mergeSql功能;慢SQL记录
    #connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 1 from dual
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    #配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
    filters: stat, wall, log4j
  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true
application-prod.yml

application-prod.yml配置文件则是我们与SpringBoot约定的线上生产环境的配置文件,里面保存的全部都是正式环境配置信息,一般在开发过程中线上环境配置信息是不需要变动的,配置完成后就只是在打包部署时修改spring.profiles.activeprod就可以了(注:根据实际项目的线上环境的配置约定名称而定)。配置信息如下所示:

代码语言:javascript
复制
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/project_prod?characterEncoding=utf8
    username: root
    password: 123456
    #最大活跃数
    maxActive: 20
    #初始化数量
    initialSize: 1
    #最大连接等待超时时间
    maxWait: 60000
    #打开PSCache,并且指定每个连接PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    #通过connectionProperties属性来打开mergeSql功能;慢SQL记录
    #connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 1 from dual
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    #配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
    filters: stat, wall, log4j
  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true

为了方便我们测试,我在本地创建的三个数据库,当然实际项目开发中你可能是数据库读写分离环境,也可能是多台服务器完全分离的环境,只需要针对不同的约定修改相对应的配置信息就可以了。

测试Profile

下面我们来创建一个控制器,使用我们上面已经创建好的SystemUserInfoJPA完成数据库的读取动作。

创建测试控制器

在上面我们为每一个环境的数据库表````都初始化了一条数据,那么我就来编写一个读取数据库的请求方法,根据我们修改的spring.profiles.active配置文件内容,是否可以改变请求数据库。控制器代码如下所示:

代码语言:javascript
复制
package com.yuqiyu.chapter38;

import com.yuqiyu.chapter38.entity.SystemUserInfoEntity;
import com.yuqiyu.chapter38.jpa.SystemUserInfoJPA;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 测试profile环境
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/10/29
 * Time:09:02
 * 码云:http://git.oschina.net/jnyqy
 * ========================
 * @author hengyu
 */
@RestController
@RequestMapping(value = "/user")
public class IndexController
{
    @Autowired
    private SystemUserInfoJPA systemUserInfoJPA;

    /**
     * 查询用户详情
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}")
    public SystemUserInfoEntity detail(@PathVariable("id") Integer id)
        throws Exception
    {
        return systemUserInfoJPA.findOne(id);
    }
}

在控制器内,我们通过访问/user/{id}请求地址,就可以获取到用户的基本信息在页面上通过Json字符串的形式展示,下面我们就来配置需要激活的Profile,访问该请求地址查看输出效果。

激活Profile

由于激活Profile的配置不属于任何一个环境分离的配置文件,所以我们不可以在devbetaprod任意一个配置文件内添加激活配置,我们知道application.ymlSpringBoot约定的配置文件,那么我就在该配置文件内配置环境分离激活,配置如下所示:

代码语言:javascript
复制
spring:
  profiles:
    active: dev

我们在application.yml配置文件内激活了dev开发环境,下面我们启动项目访问请求路径http://127.0.0.1:8080/user/1来查看界面输出内容,如下所示:

代码语言:javascript
复制
{
  id: 1,
  nickName: "开发环境用户",
  loginName: "dev",
  loginPassword: "dev_password"
}

正如我们所料,正确的输出了开发环境的用户信息,那我们修改下激活环境是不是也会编程相对应的输出呢?下面我们来证实这一点,修改激活环境为线上开发环境:

代码语言:javascript
复制
spring:
  profiles:
    active: beta

重启项目,再次访问http://127.0.0.1:8080/user/1请求路径,界面输出内容如下所示:

代码语言:javascript
复制
{
  id: 1,
  nickName: "线上测试环境用户",
  loginName: "beta",
  loginPassword: "beta_password"
}

可以看到已经改成我们需要的效果,我们只是激活了不同的环境,就轻松实现了环境的分离,正式环境也是一样的,下面我们来激活正式环境完成Package打包。

正式环境打包

有很多项目在上线打包部署的时候需要改动很多配置文件,访问地址等等配置信息,那我们采用了Profile后打包该怎么处理呢? 答案是:省心。 第一步我们只需要修改激活环境改成线上环境即可,如下所示:

代码语言:javascript
复制
spring:
  profiles:
    active: prod

第二步运行打包命令,等待打包完成。本章是采用的Idea开发工具完成的打包,Idea工具为Maven自带了命令窗口,只需要选择不同的命令双击就可以执行,如下图1所示:

图1

我们双击package命令,等待打包完成就可以了,完成后jar或者war会在target目录生成,下面我们使用Windows CMD命令行进入jar存在的目录,执行命令之前需要关掉Idea启动的项目:

代码语言:javascript
复制
java -jar chapter38-0.0.1-SNAPSHOT.jar

启动完成后,我们再次访问请求地址http://127.0.0.1:8080/user/1,查看界面输出内容:

代码语言:javascript
复制
{
  id: 1,
  nickName: "正式环境用户",
  loginName: "prod",
  loginPassword: "prod_password"
}

正确输出了prod正式环境的用户信息。

总结

Profile的加入可以让很多运维实施人员减少了太多的烦恼,在几年前部署完全都是采用修改配置文件,如果修改出错还会导致返工,既浪费了时间也浪费了精力。

建议大家项目初期尽可能的采用环境分离的方式进行构建项目!

本章代码已经上传到码云: SpringBoot配套源码地址:https://gitee.com/hengboy/spring-boot-chapter SpringCloud配套源码地址:https://gitee.com/hengboy/spring-cloud-chapter SpringBoot相关系列文章请访问:目录:SpringBoot学习目录 QueryDSL相关系列文章请访问:QueryDSL通用查询框架学习目录 SpringDataJPA相关系列文章请访问:目录:SpringDataJPA学习目录 感谢阅读!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.10.29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本章目标
  • SpringBoot 企业级核心技术学习专题
  • 构建项目
    • 配置数据库
      • 创建Entity
        • 创建JPA
          • 配置Profile环境
          • 测试Profile
            • 激活Profile
              • 正式环境打包
              • 总结
              相关产品与服务
              云数据库 SQL Server
              腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档