• 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闭包里面

  • 相关阅读:
    CF710F String Set Queries(AC自动机+二进制分组)
    P5231 [JSOI2012]玄武密码(AC自动机)
    AC自动机基础&应用
    [SDOI2011]计算器(快速幂,线性同余方程,BSGS)
    数论——欧拉定理和费马小定理
    AtCoder Beginner Contest 173 题解
    【CSP2019】树的重心(树的重心、倍增、换根)
    CF708C Centroids(换根dp,树的重心)
    凸包(Graham与Andrew算法求凸包)
    [USACO10MAR]Great Cow Gathering G(换根dp)
  • 原文地址:https://www.cnblogs.com/houzheng/p/12676222.html
Copyright © 2020-2023  润新知