gradle构建实战-从普通项目到springboot多模块项目

概述

gradle是啥东西,有什么好处这里就不说了,反正我是把我所有之前的项目大部分都重构成gradle构建了,新建项目也基本都是gradle,一个字: 用起来真爽!
前前后后也是查了很多资料,这里总结一下:

准备工作:

1 需要懂点grovy语法,我之前特意学习了一个月groovy,这里可以放一下我的学习笔记与资料,groovy很简单,会java很容易就会了: https://gitee.com/houzheng1216/groovy
2 idea与gradle安装和环境变量配置,尽量用高版本,我用的是5.4的版本
所有涉及代码笔记地址: https://gitee.com/houzheng1216/tool_maniac/tree/master/

gradle概念project和task介绍

Gradle中的所有内容都基于两个基本概念:

prject

项目(Project)和任务(Task)。每个Gradle构建都是由一个或多个project组成。每个project都是有一个或者多个任务组成。
任务之间具有依赖关系,保证了任务的执行顺序。任务代表构建执行的一些原子工作。
这可能是编译某些类,创建JAR,生成Javadoc或将一些jar或者aar文件发布到maven仓库。

task

每一个操作都可以定义为一个task任务

自定义task

//方式一
tasks.create('t2') {
    doFirst {
        println("任务执行之前的操作")
    }
    doLast {
        println("任务执行之后的操作")
    }
    println "Hello Gradle2!"
}
//方式二
// t1 依赖t2,t2先执行户t1再执行,被依赖的t2要定义在t1前面
task t1(dependsOn:t2) {
    description '这里可以添加任务说明'
   println 'Hello Gradle1!'
}
//方式三
//有两个参数,第一个是任务的名称,第二个是个lambda表达式,是任务的具体逻辑
task("t5",{
    println("自定义task")
}).dependsOn("t1") //依赖
//方式四
task('t3') {
    description '这里可以添加任务说明'
    ext{  // ext 用于自定义动态属性
        hou= "houzheng"
    }
    def uUID = UUID.randomUUID()
    println "uuid:"+uUID
    println "name:${hou}"  // 引用动态属性
}

定义好之后对应的gradle界面就会有相应操作,可直接执行

一 构建普通项目

新建普通项目

使用本地gradle

配置build.gradle

打包


生成jar地址

运行测试

二 构建web项目

新建

配置build.gradle

//声明gradle脚本自身需要使用的资源,优先执行
buildscript {
    repositories {
        mavenLocal()  // 本地maven仓库
        maven { url = 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()  //和maven中央仓库一样的另一个依赖管理仓库,主要是java
    }
}
plugins {
    id 'java'
    id 'war'   // web插件,指定为web项目
}
group 'com.hou'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
//仓库管理
repositories {
    mavenLocal()  // 本地maven仓库
    //自定义maven仓库地址
    maven { url = 'http://maven.aliyun.com/nexus/content/groups/public/' }
    jcenter()  //和maven中央仓库一样的另一个依赖管理仓库,主要是java
}

/**
 * api 用于取代compile(已被废弃)
 * api或compile关键字引用的包对于其他module来说是可见的,
 * implementation关键字引用的包对于其他module来说是不可见的。
 */
//项目依赖
dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

创建web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
</web-app>

添加tomcat

整合springmvc

添加springmvc依赖

//项目依赖
dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    //spring 系列包 5.1.6
    // spring mvc
    implementation group: 'org.springframework', name: 'spring-webmvc', version: '5.1.6.RELEASE'
    // spring 核心包
    implementation group: 'org.springframework', name: 'spring-core', version: '5.1.6.RELEASE'
    // spring beans
    implementation group: 'org.springframework', name: 'spring-beans', version: '5.1.6.RELEASE'
    // spring 上下文
    implementation group: 'org.springframework', name: 'spring-context', version: '5.1.6.RELEASE'
    // spring web
    implementation group: 'org.springframework', name: 'spring-web', version: '5.1.6.RELEASE'
    // spring orm
    implementation group: 'org.springframework', name: 'spring-orm', version: '5.1.6.RELEASE'
    // spring测试包
    implementation group: 'org.springframework', name: 'spring-test', version: '5.1.6.RELEASE'
}

新建配置文件

修改web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <!-- 防止中文参数乱码 放在前面 -->
    <filter>
        <filter-name>SetCharacterEncoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
            <!-- 强制进行转码 -->
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>SetCharacterEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- spring 配置Listener-->
    <!-- needed for ContextLoaderListener -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/applicationContext.xml</param-value>
    </context-param>
    <!-- 添加ContextLoaderListener -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--配置springmvc前端控制器 DispatcherServlet-->
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--Sources标注的文件夹下需要新建一个spring文件夹-->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <!-- 配置所有路径都走springmvc DispatcherServlet -->
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern><!--映射根路径-->
    </servlet-mapping>
</web-app>

测试

三 构建springboot项目

新建步骤都一样,build.gradle配置有点变化

//声明gradle脚本自身需要使用的资源,优先执行
buildscript {
    ext { // ext 定义动态属性
        springBootVersion = '2.1.4.RELEASE'
    }
    repositories {
        mavenLocal()   // 本地maven仓库
        maven { url = 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter() //和maven中央仓库一样的另一个依赖管理仓库,主要是java
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" // 使用动态属性
        classpath 'org.hidetake:gradle-ssh-plugin:2.6.0' // ssh依赖
    }
}
plugins {
    id 'java'
    id 'war'
}
apply plugin: 'org.springframework.boot'  //使用springboot插件
apply plugin: 'io.spring.dependency-management'  //版本管理插件
sourceCompatibility = '11'
targetCompatibility = '11'
//配置依赖仓库
repositories {
    mavenLocal()  // 本地maven仓库
    maven { url = 'http://maven.aliyun.com/nexus/content/groups/public/' }  //自定义
    jcenter()  //和maven中央仓库一样的另一个依赖管理仓库,主要是java
}

//项目依赖
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        // 使用exclude手动排除依赖,不需要指定版本号
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}
// gradle5原生支持junit,添加下面即可
test {
    useJUnitPlatform()
}

四 构建多模块项目

新建父项目与子项目结构

配置父项目setting.gradle

// 父项目名称
rootProject.name = 'blog-system'
// 导入子模块
include 'blog-web'
include 'blog-service'
include 'blog-pojo'
include 'blog-dao'
include 'blog-admin'

配置父项目build.gradle

//声明gradle脚本自身需要使用的资源,优先执行
buildscript {
    ext {
        springBootVersion = '2.1.4.RELEASE'
    }
    repositories {
        mavenLocal()  // 本地maven仓库
        maven { url = 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()  //和maven中央仓库一样的另一个依赖管理仓库,主要是java
    }
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
    }
}

//allprojects所有项目共享的配置
allprojects {
    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'java-library'
    group = 'com.hou'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = 11
    targetCompatibility = 11
}

// subprojects : 所有子模块共享的配置
subprojects {
    apply plugin: 'org.springframework.boot'  //使用springboot插件
    apply plugin: 'io.spring.dependency-management'  //版本管理插件
    // java编译的时候缺省状态下会因为中文字符而失败
    [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8'
    // 配置所有子模块的依赖仓库地址
    repositories {
        // 本地maven仓库
        mavenLocal()
        maven { url = 'http://maven.aliyun.com/nexus/content/groups/public/' }
        //和maven中央仓库一样的另一个依赖管理仓库,主要是java
        jcenter()
    }
    //所有子模块共有依赖
    dependencies{
        // gradle5.0版本以上引入需要这种形式
        compileOnly 'org.projectlombok:lombok:1.18.8'
        annotationProcessor 'org.projectlombok:lombok:1.18.8'
        implementation 'org.codehaus.groovy:groovy'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }
}

配置子项目依赖关系,比如dao依赖model.service依赖dao,web依赖service

dependencies {
    //需要使用api,即web等模块引入从模块后,dao对web等模块是可见的,即间接依赖
    api (project(':blog-dao'))
    implementation 'org.springframework.boot:spring-boot-starter'
}

五 ssh部署

脚本添加ssh插件

添加ssh插件

//关闭tomcat
task shutdownTomcat() {
    doLast {
        ssh.run {
            session(remotes.deployServer) {
                println 'shut down tomcat...'
                //编写脚本
                execute "/usr/local/app/apache-tomcat-9.0.24/bin/shutdown.sh"
                // 执行脚本
//                executeScript  '''#!/bin/sh
//                        rm -rf /opt/app/apache-tomcat-7.0.67/webapps/cloud_server
//                        rm -f /opt/app/apache-tomcat-7.0.67/webapps/cloud_server.war
//                    '''
            }
        }
    }
}
////删除项目
task del(dependsOn:shutdownTomcat) {
    doLast {
        ssh.run {
            session(remotes.deployServer) {
                println 'start deleting...'
                execute "rm -rf /usr/local/app/apache-tomcat-9.0.24/webapps/slf4*"
            }
        }
    }

}
//部署到服务器
task depoly(dependsOn: del) {
    doLast {
        ssh.run {
            session(remotes.deployServer) {
                println 'start copying war...'
                put from: buildDir.toString() + '/libs/slf4j.war', into: '/usr/local/app/apache-tomcat-9.0.24/webapps'
                execute "/usr/local/app/apache-tomcat-9.0.24/bin/startup.sh"
            }
        }
    }
}

编写部署task

//关闭tomcat
task shutdownTomcat() {
    doLast {
        ssh.run {
            session(remotes.deployServer) {
                println 'shut down tomcat...'
                //编写脚本
                execute "/usr/local/app/apache-tomcat-9.0.24/bin/shutdown.sh"
                // 执行脚本
//                executeScript  '''#!/bin/sh
//                        rm -rf /opt/app/apache-tomcat-7.0.67/webapps/cloud_server
//                        rm -f /opt/app/apache-tomcat-7.0.67/webapps/cloud_server.war
//                    '''
            }
        }
    }
}
////删除项目
task del(dependsOn:shutdownTomcat) {
    doLast {
        ssh.run {
            session(remotes.deployServer) {
                println 'start deleting...'
                execute "rm -rf /usr/local/app/apache-tomcat-9.0.24/webapps/slf4*"
            }
        }
    }

}
//部署到服务器
task depoly(dependsOn: del) {
    doLast {
        ssh.run {
            session(remotes.deployServer) {
                println 'start copying war...'
                put from: buildDir.toString() + '/libs/slf4j.war', into: '/usr/local/app/apache-tomcat-9.0.24/webapps'
                execute "/usr/local/app/apache-tomcat-9.0.24/bin/startup.sh"
            }
        }
    }
}

注意: 如果报错 status 1 ,则看日志提示,需要配置JAVA_HOME环境变量,看下面注意点

六 使用注意点

1 多模块项目中如果有多个jar项目,需要指定一个mainClass:

2 使用ssh部署的时候需要配置环境变量

通过SSH直接执行远程命令和脚本
这种方式会使用Bash的non-interactive + non-login shell模式,它会创建一个shell,执行完脚本之后便退出,不再需要与用户交互。
no-login shell,顾名思义就是不是在登录Linux系统时启动的(比如你在命令行提示符上输入bash启动)。它不会去执行/etc/profile文件,而会去用户的HOME目录检查.bashrc并加载。
所以需要在登录用户的HOME目录的.bashrc中添加需要的环境变量。

3 一些构建的任务等,如果不想在配置阶段就执行,即刷新build.gradle的时候,就必须放到 doLast或者doFirst闭包里面

原文地址:https://www.cnblogs.com/houzheng/p/12676222.html