使用Gradle构建多模块SpringBoot项目

使用Gradle构建多模块SpringBoot项目

本项目使用Gradle构建SpringBoot项目,将不同的业务进行不同的模块划分(不做微服务与分布式架构);
- 编辑器:Intellij IDEA
- 构建工具:Gradle3.5
- SpringBoot版本:1.5.8
- 版本管理:GitHub
- 个人GitHub地址:https://github.com/fanlongfei0212
- 项目Clone地址:https://github.com/fanlongfei0212/demo.git


项目构建
  • 首先创建一个项目,我们使用IDEA构建一个Gradle Java项目,作为项目的最外层,只做为整个项目的容器,所以最外层项目只构建为普通的Gradle Java项目即可;
    这里写图片描述

  • 填写GroupId与ArtifactId;
    一般正式项目的GroupId为com.*开头,因为此项目为个人项目,所以使用pers.*开头,具体规则大家可以参考命名规范,ArtifactId为项目名称;

    这里写图片描述

  • 点击Next,进入Gradle配置页面;
    选择Use local gradle distribution,配置自己本地的Gradle地址;
    点击Next,Project name自动为ArtifactId,Project location为IDEA默认(或你上一次设置)的WorkSpace,分配WorkSpace;
    点击Finish,完成Gradle Java项目的创建

    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述

  • 项目已经创建好了,我们开始创建各个模块,在不同项目中,模块划分的方式也会不同,具体的模块划分可以按照实际项目的需求进行划分;
    在此Demo中,将模块划分为:
    全局工具模块:tools-common(项目中所有模块的全局工具类,基础模块依赖此模块,下面会讲到基础模块)
    视图模块:views-demo(项目中的视图模块,比如:APP所需接口、管理后台所需接口,需要进行数据展示的模块,都会被此模块依赖)
    业务模块:service-demo1(将项目中不同业务进行模块化的区分,一般在项目中,业务模块是最多的,而且在某个业务模块中需要其他业务模块作为支撑的可以进行Gradle依赖,但要避免循环依赖)
    基础模块:basic-base(项目中所有业务模块的支撑,此模块中提供的基础服务是所有业务模块中都要用到的,所有业务模块都要依赖此模块,此模块依赖全局工具模块,这样,所有的模块都相当于间接依赖了全局工具模块)

  • 1.创建全局工具模块:
    右键项目,点击 New -> Moduel,选择Spring Initializr,点击Next

    这里写图片描述
    这里写图片描述

  • 2.配置模块:
    设置Group,最好与项目的GroupId保持一致;
    设置Artifact,模块名称;
    设置Type,我们使用的是Gradle进行项目构建,所以选择Gradle Project;
    点击Next

    这里写图片描述

  • 3.配置SpringBoot,也可以不再此处进行配置,直接在模块中的Gradle文件中添加依赖也可以起到同样的作用,最后在同一说明处会有讲解,我们先在此处进行配置:
    Core:DevTools(项目中一些开发工具,比如热部署等)、Lombok(消除冗长的Java代码,比如get、set、构造函数等,可以直接使用注解);
    Web:Web(Spring的一些Web配置);
    SQL:JPA、MySQL(我使用的是MySQL,大家可以根据实际情况进行数据库选择);
    Ops:Actuator(项目监控);
    点击Next,会发现Module name为Artifact,和创建项目时一样,点击Finish

  • 注:大家可以根据自己的项目情况进行SpringBoot的配置,配置好之后再窗体中的右边Selected Dependencies可以查看已选的SpringBoot配置
    这里写图片描述
    这里写图片描述

  • 4.设置Use local gradle distribution配置Gradle,选择本地的Gradle地址,点击OK,完成创建模块;
    这里写图片描述
    这里写图片描述

  • 5.进行Gradle配置,大家可以看到,右边的的Gradle视图也多了一个tools-common的模块,但是有一个问题,他和项目模块是平级的,在Gradle项目中,根项目应该在最外层,其他模块都应包含在根项目中,我们设置最外层settings.gradle文件,把模块include到最外层的项目中,然后刷新Gradle
    这里写图片描述
    大家会发现有的时候可能会出现两个根,其实只有一个,在Mac下初步判定是IDEA的兼容或显示问题,大家删除最下面的那个就可以了(选中第二个根,点击Gradle视图上的‘-’即可),正常删除的时候Gradle会出现删除提示,但是删除错误显示的时候你会发现,没有提示,这是正常的,因为具有真实存在的根
    这里写图片描述
    这里写图片描述

  • 6.所有的模块进行统一步骤的创建
    这里写图片描述

  • 7.进行所有模块的Gradle配置,配置各个模块之间的依赖,将根Gradle的sourceCompatibility设置为1.8(我的JDK使用的是1.8),然后刷新Gradle,删除多余的根(如果出现的话)
    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述

  • 8.整理项目中文件
    将无用的文件进行删除;
    删除所有模块中的gradlew文件
    删除所有模块中的gradlew.bat文件
    删除所有模块中的gradle文件夹
    删除所有模块中的.gitignore文件,在项目最外层配置.gitignore文件,做为整个项目的git提交忽略配置

    这里写图片描述
    这里写图片描述

  • 9.配置SpringBoot的application.properties文件:
    将所有模块application.properties进行重新命名修改,在多模块项目中,视图模块作为最外层的运行模块,也就是说views-demo这个模块最后会被build成jar包(或者war包)运行在服务器上,作为最外层容器,当容器进行加载的时候会加载所有的application.properties文件,因为每个模块都可能会有针对本模块配置,我们要保证所有的模块配置都要被SpringBoot加载,了解过SpringBoot的童鞋们都知道,SpringBoot的大部分配置项都可以在application.properties中进行直接配置,但是在views-demo加载所有模块的application.properties文件的时候,由于名称一致,这时就会出现覆盖加载的问题,导致一部分的配置无法加载到,这时,就需要我们修改各个模块的application.properties文件的名称,保证所有模块application.properties中的配置项都可以被SpringBoot加载;
    这样确实可以解决覆盖加载的问题,但是会衍生出一个新的问题,就是SpringBoot默认只会去加载名称为application.properties中的配置项,为了解决这个问题,我们可以使用@Profile注解去配置SpringBoot的加载环境,在每个模块中都去做一个配置Bean,然后将所有修改过的资源文件都配置到views-demo中的application.properties文件中,使我们修改过名称的application.properties文件都被SpringBoot加载;

    basic-base模块
    这里写图片描述
    这里写图片描述
    service-demo1模块
    这里写图片描述
    这里写图片描述
    tools-common模块
    这里写图片描述
    这里写图片描述
    views-demo模块
    这里写图片描述
    这里写图片描述
    在views-demo模块中统一加载修改过的资源文件
    这里写图片描述
    这里写图片描述

  • 10.配置数据源:
    在所有配置都完成之后,我们似乎可以运行项目了,但是其实还是最后一个地方需要进行配置,那就是配置数据源,不知道大家是否再记得,我们在配置SpringBoot的时候勾选了SQL块中的Jpa和MySQL,如果不进行数据源配置的话运行就会抛出:Cannot determine embedded database driver class for database type NONE异常;

    这里写图片描述
    配置数据源以及其他基础配置,配置完成之后我们运行views-demo项目,并进行build(打包:jar或war,我只做生成jar文件测试,平时服务器上也是部署jar文件)测试,如果项目无法build的话,说明程序还是存在问题的;
    这里写图片描述
    启动测试
    这里写图片描述
    这里写图片描述
    这里写图片描述
    build测试是否可以生成jar文件,在build的时候可能会出现一个异常,是因为各个模块中存在与main同级的test的问题,将test删除即可
    这里写图片描述
    这里写图片描述
    删除各个模块中的test后进行build,build成功后,在views-demo模块的build->libs中会生成views-demo-0.0.1-SNAPSHOT.jar,我们将jar包直接在liunx环境下进行启动,看是否可以成功运行;
    这里写图片描述
    这里写图片描述
    运行WorkSpace中的views-demo-0.0.1-SNAPSHOT.jar
    这里写图片描述
    这里写图片描述
    这里写图片描述

出现问题以及其他说明

项目结构:
basic-base(基础模块):所有业务模块都需要用到的业务逻辑service;
tools-common(全局工具模块):所有模块需要的工具类,说到这,大家可能会有一个疑问,在上面的截图中,大家会发现在每个模块的入口处有一个包,包结构为:
pers.fly.common
- - - - - - - -|config
- - - - - - - -|tools
在项目的结构中已经存在了一个common的工具模块,为什么每个包下还会存在tools这种工具包。又一次,我的一个朋友曾经和我说,在项目中你会发现有的工具类只有本项目才会用到,那为什么不在每个模块中建立一个只放置本模块的工具类的包呢,然后把所有模块都会用到的工具类放到全局公共区域;这样的规划的话显然是更合理的;
service-demo1(业务模块):此项目只为演示使用Gradle构建SpringBoot多模块项目,在实际项目开发中,会存在多个业务模块,所有业务模块都已service-开头,所以此项目中只有一个业务模块,并且以demo1命名,在实际项目中最好不要出现数字,相关规则大家查看Java的命名规范,结合实际情况;
views-demo(视图模块):存放对外提供的接口,Controller接口的放置位置,针对具体的业务场景或者不同的终端;比如,这个视图模块只放置**的业务模块的接口,或者只放置对APP端提供的接口,或者只放置对PC端提供的接口,或者只放置对微信端的接口等等;在实际项目中,视图层模块也可能存在多个;

@Profile的使用:
学习过SpringBoot的童鞋肯定知道@Profile,在这我要说明一点,我在学习SpringBoot中的时候,网上的一些资料和书本中都有讲解过@Profile的作用,大部分的资料和书籍说@Profile是为了方便区分项目环境而进行的配置,在实际项目中,项目环境会分为开发环境、测试环境、生产环境(标准的项目环境应该还会存在预发布环境),在这些环境中某些配置是不一样的,比如数据库的链接地址,连接池的配置或者等等其他的一些配置,然后使用@Profile是为了区分这些环境去配置一些不同的application.properties资源文件配置;我个人认为@Profile既然可以去做到将不同的环境区分,并且可以指定某个或同时指定多个环境的配置,那为什么只能作为项目环境的区分,如果要区分项目环境的话,有很多方法,比如在使用Git作为版本管理的时候,我们可以使用分支来作为区分,而且SpringBoot的配置文件的加载顺序是从与项目平级的配置文件开始加载,然后在加载项目中的配置文件,在加载模块中的配置文件,它的优先级是从外到内的(配置文件中,如果存在Java类配置的话Java类的优先级是高于application.properties的优先级的),在上不同的环境时我们可以在服务器上和jar包放置不同环境的application.properties文件也可以做到项目环境的区分;我还查阅了官方文档,官方文档是这样描述的:
这里写图片描述
大概意思就是可以使用命名约定(application-{**}.properties)去加载、定义应用程序,官方文档确实也使用了development、production去做一些例子,但个人认为@Profile不应该仅仅只是为了区分项目环境,最重要的是它可以灵活的去定义一些配置;

配置完数据源之后还是会抛出Cannot determine embedded database driver class for database type NONE异常问题
在使用Gradle构建SpringBoot项目的时候,出现过这样的问题,在加载多个模块的时候,明明配置了好了数据源也指定了数据库的类型,但还是会抛出,并且在Run/Debug Configurations中确实是以Application方式启动并且也指定了Working directory的项目地址,但是还是不行,后来发现将.idea删除,重新使项目配置加载,然后这个问题就解决了,具体为什么我也不是特别明白,可能是idea的缓存?或者是Mac下idea的不兼容?我用的是Mac,不知道Windows下有没有同样的问题;

关于build失败的问题
在进行build的时候会出现一个异常,在上面的截图中build测试的时候也说了这个问题,抛出的异常信息显示是关于测试文件的加载问题,具体为什么会出现这样的问题,详细原因目前为止还没有找到,当前的解决方法就是删除test模块,删除之后确实可以进行build,但是终归不是长久之计,一个完整的项目怎么能没有测试呢,这个问题接下来还是要处理一下;

说明:以上均为个人见解,如果有不对的地方或者各位童鞋有不同的见解以及意见,欢迎留言指正~~