木心

毕竟几人真得鹿,不知终日梦为鱼

导航

构建工具gradle教程

录:

1、项目自动化
2、安装Gradle
3、groovy介绍
4、新建一个gradle工程,打包成jar,运行其中的类的main()方法
5、构建脚本和自定义任务
6、gradle开发web工程
7、多项目构建

1、项目自动化    <--返回目录

  构建工具的作用:依赖管理,测试、打包、发布

  主流构建工具:1)Ant 编译、测试、打包  2)Maven 依赖管理、发布  3)Gradle

  Gradle是什么:一个开源的项目自动化构建工具,建立在Apach Ant和Apache Maven概念的基础上,并引入了基于Groovy的特定领域语言(DSL),而不再使用XML形式管理构建脚本。

 

2、安装Gradle    <--返回目录

  确保已经安装JDK,java -version

  从Gradle官网(https://gradle.org)下载压缩包,解压

  配置环境变量 GRADLE_HOME,添加到path  %GRADLE_HOME%\bin

  验证是否安装成功 gradle -v

 

3、groovy介绍    <--返回目录

  groovy是用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用这种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。

  与Java比较

1)groovy完全兼容java的语法
2)分号是可选的
3)类、方法默认是public
4)编译器给属性自动添加getter/setter方法
5)属性可以直接用点号获取
6)最后一个表达式的值会被作为返回值

  使用 IDEA 的 Tools -> Groovy Console 测试 groovy的简单用法

  新建一个Project,选择gradle工程

  默认的gradle工程结构

 

  选择菜单 Tools -> Groovy Console作为环境进行测试

  groovy 语法相对 java 的一些区别

public class User { // 类、方法默认是public,类的修饰 public 可以省略
    private Integer id;
    private String name // 分号是可选的
    public User(Integer id, String name) { // 类、方法默认是public,方法上 public 可以省略
        this.id = id;
        this.name = name;
    }
    String getUserInfo() {
        //return "id:" + id + ", name:" + name;
        //最后一个表达式的值会被作为返回值,return可以省略
        // gradle 中字符串可以使用单引号,双引号,三单引号, 三双引号
        //'d:' + id + ', name:' + name // 单引号
        //"id:" + id + ", name:" + name // 双引号
        //"id:${this.id}, name: ${this.name}" // 双引号,使用变量
        """// 三双引号,使用变量
            id:${this.id}
            name: ${this.name}
        """
    }
    // 编译器给属性自动添加getter/setter方法
}
User u = new User(1, "xxx");
// 属性可以直接用点号获取
println u.id
println u.name

def info = u.getUserInfo()
println info

  groovy 的一些特定用法

// 1 可选的类型定义
def version = 1

// 2 assert
assert version == 1

// 3 括号是可选的
println version

// 4 字符串
def s1 = 'zs'
def s2 = "${s1} good good study"
def s3 =
'''好好学习
天天向上
'''
def s4 =
"""${s1}
好好学习
天天向上
"""
println s1
println s2
println s3
println s4

// 5 集合api
// list
def list = ['a', 'b']
list << 'c' // 追加
assert list.getClass() == ArrayList // 对应的Java类型是ArrayList

// map
def map = ['key1': 10, 'key2': 'val2']
map.key3 = 30 // 添加
println map
println map.getClass() // class java.util.LinkedHashMap

  闭包

// 定义一个闭包,包含参数
def c1 = {
    v ->
        println v
}
// // 定义一个闭包,不含参数
def c2 = {
    println 'hello'
}
// 将闭包作为方法参数
def fun1(Closure closure) {
    closure('param')
}
def fun2(Closure closure) {
    closure()
}
fun1(c1)
fun2(c2)

 

4、新建一个gradle工程,打包成jar,运行其中的类的main()方法    <--返回目录

  新建一个Project,选择gradle工程

  默认的gradle工程结构

  执行gradle的jar任务

  生成的jar的位置

  

4.1、运行 com.oy.App#main()方式一

  App类很简单,不过使用了一些第三方包 commons-lang3 等来测试运行 main() 方法时如何加载第三方包

public class App {
    public static void main(String[] args) {
        String s = "hello gradle";
        System.out.println(s);
        System.out.println(StringUtils.capitalize(s));
        System.out.println(System.getProperty("java.ext.dirs"));
    }
}

 

  打开cmd(powshell不行?),执行 java -Djava.ext.dirs=.;./lib com.oy.App   ,其中-D用来添加系统变量,java.ext.dir 指定外部挂载的jar,com.oy.App时包含main()方法的类名

 

4.2、运行 com.oy.App#main()方式二:gradle构建可执行jar

  在build.gradle中添加

jar {
    manifest {
        attributes 'Main-Class': 'com.oy.App'
        // 添加所有依赖,用空格隔开
        attributes 'Class-Path': 'lib/commons-lang3-3.12.0.jar lib/commons-collections4-4.1.jar'
    }
}

  生成的 gradle-demo01-1.0-SNAPSHOT.jar 的 META-INF/MANIFEST.MF 文件的内容

Manifest-Version: 1.0
Class-Path: lib/commons-lang3-3.12.0.jar
Main-Clas: com.oy.App

  执行 java -jar gradle-demo01-1.0-SNAPSHOT.jar

 

5、构建脚本和自定义任务    <--返回目录

5.1、构建脚本介绍

  构建块:gradle构建中的两个基本概念是项目(project)和任务(task),每个构建至少包含一个项目,项目中包含一个或多个任务。在多项目构建中,一个项目可以依赖于其他项目,类似的,任务可以形成一个依赖关系图来确保他们的执行顺序。

 

  项目project:一个项目代表一个正在构建的组件(比如一个jar文件),当构建启动后,gradle会基于build.gradle实例化一个org.gradle.api.Project类,并且能够通过project变量使其隐式可用。

  项目project的属性:group、name、version,

  项目project的方法:apply、dependencies、repositories、task

  属性的其他配置方式:ext、gradle.properties

 

  任务task: 任务对应org.gradle.api.Task。主要包括任务动作和任务依赖。任务动作定义了一个最小的工作单元。可以定义依赖于其他任务、动作序列和执行条件。

   任务task:dependsOn 依赖的任务

       doFirst 在动作列表的最前添加动作、doLast(<<)在动作列表最后添加动作

5.2、自定义任务

def createDir = {
    path ->
        File dir = new File(path)
        if (!dir.exists()) {
            dir.mkdirs()
        }
}
task makeJavaDir() {
    def paths = ['src/main/java', 'src/main/resources', 'src/test/java', 'src/test/resources']
    doFirst {
        paths.forEach(createDir)
    }
}

task makeWebDir() {
    // 依赖 makeJavaDir 这个任务
    dependsOn 'makeJavaDir'
    def paths = ['src/main/webapp']
    doLast {
        paths.forEach(createDir)
    }
}

5.3、构建生命周期

  初始化 -> 配置 -> 执行

// 配置
task loadVersion {
    // 修改project的version
    project.version = '1.0'
}
// 执行
task loadVersion << {
    print 'success'
}

5.4、依赖管理

// 当有依赖冲突是,gradle默认会帮我们解决,使用冲突的jar的最高版本
// 修改为:依赖冲突时,直接构建失败
configuration.all {
    resolutionStrategy {
        failOnVersionConflict()
    }
}

// 解决依赖冲突办法一:排除依赖
compile('org.hibernate:hibernate-core:3.6.3.Final') {
    exclude group: "org.slf4j", module: "slf4j-api"
}

// 解决依赖冲突办法二:强制指定一个版本
configuration.all {
    resolutionStrategy {
        force 'org.slf4j:slf4j-api:1.7.24'
    }
}

5.5、自动化测试

   测试发现:哪些类会被 gradle 的 "build" 发现为测试用例

1)任何继承自 junit.framework.TestCase或groovy.util.GroovyTestCase的类
2)任何被@RunWith注解的类
3)任何至少包含一个被@Test注解的类

5.6、发布

apply plugin: 'maven-publish'
publishing {
    publications {
        myPublish(MavenPublication) {
            from components.java
        }
    }
    repositories {
        maven {
            name "myRepo"
            url "maven私服地址"
        }
    }
}

 

6、gradle开发web工程    <--返回目录

  使用 'war'插件

    build.gradle

plugins {
    id 'java'
    id 'war'
}

group 'org.example'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenLocal()       // 使用本地maven仓库
    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    mavenCentral()     // 使用maven中心仓库
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'org.springframework', name: 'spring-context', version: '5.0.2.RELEASE'
    compile group: 'org.springframework', name: 'spring-web', version: '5.0.2.RELEASE'
    compile group: 'org.springframework', name: 'spring-webmvc', version: '5.0.2.RELEASE'
    compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
    compileOnly group: 'javax.servlet', name: 'jsp-api', version: '2.0'
}

  web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="oy" version="2.5">
    <display-name>project-manager</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    <!-- 初始化spring容器 -->
<!--    <context-param>-->
<!--        <param-name>contextConfigLocation</param-name>-->
<!--        <param-value>classpath:springmvc.xml</param-value>-->
<!--    </context-param>-->
<!--    <listener>-->
<!--        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>-->
<!--    </listener>-->

    <!-- 解决post乱码 -->
    <filter>
        <filter-name>CharacterEncodingFilter</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>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- springmvc的前端控制器 -->
    <servlet>
        <servlet-name>project-manager</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation,
             springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>project-manager</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
View Code

  IDEA配置local server

 

  启动后服务:http://localhost:8001/hello/test , 因为配置的server context为"/" ,8001后面就没有服务名称

  查看关联的本地tomcat/webapps,上面服务发布路径就为ROOT

 

 7、多项目构建    <--返回目录

  项目模块化:在企业项目中,包层次和类关系比较复杂,把代码拆分成模块通常是最佳实践,这需要你清晰的划分功能的边界,比如把业务逻辑和数据持久化拆分开来。项目符合高内聚低耦合时,模块化就变得很容易,这是一条非常好的软件开发实践。

  测试项目结构

  父工程下的build.gradle

subprojects {
    group 'org.example'
    version '1.0-SNAPSHOT'

    repositories {
        mavenLocal()       // 使用本地maven仓库
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        mavenCentral()     // 使用maven中心仓库
    }
}

  settings.gradle

rootProject.name = 'parent'
include 'dao'
include 'service'
include 'web'

  web模块

   web模块下的build.gradle

plugins {
    id 'java'
    id 'war'
}
sourceCompatibility = 1.8

dependencies {
    compile project(":service")
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'org.springframework', name: 'spring-context', version: '5.0.2.RELEASE'
    compile group: 'org.springframework', name: 'spring-web', version: '5.0.2.RELEASE'
    compile group: 'org.springframework', name: 'spring-webmvc', version: '5.0.2.RELEASE'
    compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
    compileOnly group: 'javax.servlet', name: 'jsp-api', version: '2.0'
}

  service模块下的build.gradle

plugins {
    id 'java'
}
sourceCompatibility = 1.8

dependencies {
    compile project(":dao")
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

  dao模块下的build.gradle

plugins {
    id 'java'
}
sourceCompatibility = 1.8

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

  同前面一样配置local server

 

   查看关联的本地tomcat/webapps,上面服务发布路径就为ROOT,查看 WEB-INF/lib即为web工程所有的依赖,可以看到server模块和dao模块都被添加进来了

 

参考:

  1)Gradle构建可执行Jar包

posted on 2021-11-01 09:59  wenbin_ouyang  阅读(1144)  评论(0编辑  收藏  举报