Начало работы с языком Groovy

Java Spring maven Groovy

предисловие

Так как проект должен использовать язык Groovy, я провел его грубое изучение за последние два дня.Эта статья является кратким итогом исследования.Основное содержание относится к официальной документации (официальная документация Groovy находится на все еще очень хорошо, и настоятельно рекомендуется к прочтению), я надеюсь, что эта статья будет полезна студентам, которые готовятся научиться использовать или интересуются Groovy. Если что-то не так, пожалуйста, укажите. Понимание этого язык все еще относительно поверхностен.

Введение

GroovyЭто динамический/гибкий язык программирования, основанный на платформе JVM под Apache.В языковом дизайне он вбирает в себя отличные возможности языков Python, Ruby и Smalltalk.Синтаксис очень лаконичен и красив, а эффективность разработки также очень высока. (Эффективность разработки языка программирования и производительность противоречивы. Чем более продвинутый язык программирования, тем хуже производительность, потому что это означает более низкоуровневую инкапсуляцию, но эффективность разработки будет выше. Кроме того, Groovy может быть бесшовно связан с языком Java.При написании Groovy, если вы забудете грамматику, вы можете продолжать писать непосредственно в соответствии с грамматикой Java, или вы можете вызвать скрипт Groovy на Java, который может работать очень хорошо, что эффективно снижает стоимость изучения Groovy для разработчиков Java. Groovy не заменяет Java, а дополняет и дополняет друг друга.Какой язык используется, зависит от решаемой задачи и варианта использования.

быстрый старт

  1. Загрузите пакет средств разработки Groovy (GDK)
    groovy.groovy-wolf.org/download.Контракт…
  2. Создать Groovy-проект
    Если вы используете IDEA, вам необходимо установить подключаемый модуль поддержки Groovy. После завершения установки в новом проекте появится параметр проекта Groovy. Выберите проект Groovy и свяжите библиотеку Groovy. Конечно, вы также можете создать это напрямую..groovyФайл запускается прямо из командной строки.
  3. Hello World
    Чтобы вывести «hello world» в Java, вам нужно создать класс, подобный следующему, а затем создать основной метод.
    public class Hello {
     public static void main(String[] args) {
         System.out.println("hello world");
     }
    }
    В Groovy их можно опустить, а следующие четыре метода могут вывести «hello world».
    System.out.println("hello world");
    System.out.println "hello world";
    println("hello world")
    println 'hello world'
    Конечно, его также можно запустить в основном методе класса, как в Java.
    class Hello {
     static void main(args) {
         println 'hello world'
     }
    }
    Если файл сценария Groovy содержит только исполняемый код и не содержит определения класса, компилятор Groovy создаст подкласс класса Script, имя класса будет таким же, как имя файла файла сценария, а код сценария будет включен в файл с именемrunметод, основной метод также генерируется как точка входа всего скрипта. Следовательно, как язык платформы JVM, он по сути такой же, как Java.

Некоторые отличия от Java

Импорт по умолчанию

Groovy импортирует следующие пакеты и классы по умолчанию, нет необходимости использоватьimportОператоры импортируются явно.

java.io.*
java.lang.*
java.math.BigDecimal
java.math.BigInteger
java.net.*
java.util.*
groovy.lang.*
groovy.util.*

несколько методов

В Groovy вызываемый метод будет выбран во время выполнения. Этот механизм, известный как диспетчеризация во время выполнения или использование нескольких методов, выбирает методы на основе типов аргументов во время выполнения. Java использует противоположную стратегию: во время компиляции методы выбираются на основе объявленного типа.

Ниже приведен пример, в котором один и тот же код Java выполняется по-разному в средах Java и Groovy.

int method(String arg) {
    return 1;
}
int method(Object arg) {
    return 2;
}
Object o = "Object";
int result = method(o);
// In Java
assertEquals(2, result);
// In Groovy
assertEquals(1, result);

Разница в том, что Java использует статические типы данных, o объявляется как объект Object, тогда как Groovy выбирает, когда метод фактически вызывается во время выполнения. Поскольку вызов относится к объекту типа String, естественно вызывать версию метода String.

Синтаксис инициализации массива

В Groovy блоки {...} зарезервированы для замыканий, поэтому вы не можете инициализировать массивы следующим образом, как в Java.

int[] array = { 1, 2, 3}

Должно быть следующее

int[] array = [1,2,3]

POJO

Groovy неявно создает методы получения и установки по умолчанию и предоставляет конструктор с параметрами. Следующие два эквивалентны.

// In Java
public class Person {
    private String name;
    Person(String name) {
        this.name = name
    }
    public String getName() {
        return name
    }
    public void setName(String name) {
        this.name = name
    }
}

// In Groovy
class Person {
    String name
}

def person = new Person(name: '张三')
assert '张三' == person.name
person.name = '李四'
//person.setName('李四')
assert '李四' == person.getName()

пакетный доступ

В Java, если модификатор доступа не указан явно (public、protected、private), то по умолчанию используется пакетный доступ, но в Groovy по умолчанию используетсяpublic, поэтому вам нужно использовать@PackageScopeаннотация.

class Person {
    @PackageScope String name
}

Блок операторов ARM

Блок операторов ARM (автоматическое управление ресурсами) (или синтаксис TWR) был представлен начиная с Java 7 для уменьшения сложности кода операций ввода-вывода, но Groovy его не поддерживает. Напротив, Groovy предоставляет множество методов, основанных на замыканиях, которые не только достигают того же эффекта, но и являются более лаконичными и элегантными.

//In Groovy
Path file = Paths.get("/User/lihengming/test.txt");
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }

} catch (IOException e) {
    e.printStackTrace();
}

//In Groovy
new File('/User/lihengming/test.txt').eachLine('UTF-8') {
   println it
}
//或者这样,更接近于Java的方式
new File('/User/lihengming/test.txt').withReader('UTF-8') { reader ->
   reader.eachLine {
       println it
   }
}
//如果只是为了读取并打印出文本的内容的话,下面是最简洁的方式
print new File('/User/lihengming/test.txt').text

внутренний класс

Groovy также поддерживает внутренние классы, а реализация такая же, как в Java, но ее не следует рассматривать как противоречащую спецификации языка Java, продолжайте качать головой о вещах, которые отличаются. В Groovy внутренние классы выглядят примерно так же, как реализация класса groovy.lang.Closure.

//静态内部类
class A {
    static class B {}
}
new A.B()

//匿名内部类
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

CountDownLatch called = new CountDownLatch(1)

Timer timer = new Timer()
timer.schedule(new TimerTask() {
    void run() {
        called.countDown()
    }
}, 0)

assert called.await(10, TimeUnit.SECONDS)

Лямбда-выражения

Java 8 поддерживает лямбда-выражения и ссылки на методы.

Runnable run = () -> System.out.println("Run");
list.forEach(System.out::println);

Лямбда-выражения Java 8 можно рассматривать как анонимные внутренние классы. Groovy использует не этот синтаксис, а замыкания.

Runnable run = { println 'run' }
list.each { println it } // or list.each(this.&println)

GString

Поскольку строковые литералы, заключенные в двойные кавычки, интерпретируются как значения GString (сокращение от «Groovy strings»), если строковый литерал в классе содержит символ доллара ($), то при использовании Groovy при компиляции с компилятором Java Groovy будет скорее всего, не удастся скомпилировать или получить результаты, отличные от компиляции с Java.

Как правило, Groovy автоматически преобразует GString и String, если API объявляет тип формального параметра. Будьте осторожны с API-интерфейсами Java, параметрами которых являются Object , вам необходимо проверить их фактический тип.

Строковые и символьные литералы

В Groovy литералы, созданные с помощью одинарных кавычек, являются объектами типа String, а литералы, созданные с помощью двойных кавычек, могут быть объектами String или GString Конкретная классификация определяется наличием интерполяции в литерале.

assert 'c'.getClass()==String
assert "c".getClass()==String
assert "c${1}".getClass() in GString

Базовая грамматика

  • Операторы Groovy не требуют точек с запятой (;) в конце, конечно же, не сообщит об ошибке, ведь он полностью совместим с синтаксисом Java.
  • В Groovy==Эквивалент в Javaequalsметод.

Примечания

Комментарии, как и Java, поддерживают однострочные (//),многострочный(/* */) и комментарии к документации (/** */)

Кроме того, он также поддерживает строку Shebang (система UNIX поддерживает специальный однострочный комментарий, называемый строкой Shebang, который используется для указания среды выполнения сценария, чтобы его можно было запустить непосредственно в терминале). Знак # должен быть первый символ файла.

#!/usr/bin/env groovy
println "Hello from the shebang line"

Переменная

Модификатор доступа по умолчанию для переменных, определенных в Groovy:public, определение переменной следует соглашению об именах переменных Java.Имя переменной начинается с буквы, символа подчеркивания или знака доллара $ и может содержать буквы, цифры, символы подчеркивания и знака доллара $, за исключением ключевых слов. В дополнение к этим правилам, если Groovy определяет переменную в одной строке для определения типа, точка с запятой в конце может быть опущена, но если несколько переменных занимают одну строку, переменные должны быть разделены точкой с запятой.

Способ, которым Groovy определяет переменные, подобен Java, разница в том, что Groovy предоставляетdefИспользуется ключевое слово, которое может опускать определение типа переменной и выполнять вывод типа на основе значения переменной.

def a = 123
def b = 'b'
def c = true 
boolean d = false
int e = 123

Если буквальное значение переменной определено как число, тип будет автоматически скорректирован в соответствии с размером числа.

def a = 1
assert a instanceof Integer

// Integer.MAX_VALUE
def b = 2147483647
assert b instanceof Integer

// Integer.MAX_VALUE + 1
def c = 2147483648
assert c instanceof Long

// Long.MAX_VALUE
def d = 9223372036854775807
assert d instanceof Long

// Long.MAX_VALUE + 1
def e = 9223372036854775808
assert e instanceof BigInteger

Для литералов с плавающей запятой Groovy по умолчанию использует BigDecimal для точности.

def decimal = 123.456
println decimal.getClass() // class java.math.BigDecimal

Groovy предоставляет более простой способ объявления типов для числовых типов: суффиксы типов

- Integer 使用I或i
- Long 使用L或l
- BigInteger 使用G或g
- BigDecimal 使用G或g
- Double 使用D或d
- Float 使用F或f

Пример использования

def a = 123I
assert a instanceof Integer
def b= 123L
assert b instanceof Long

нить

В Groovy есть два типа строк: обычные строки (java.lang.String) и интерполированная строка (groovy.lang.GString).
Используйте одинарные кавычки для обычных строк

println 'hello'

Используйте двойные кавычки для интерполяции строк

def name = '张三'
println "hello $name"

Кроме того, он также поддерживает метод записи тройных одинарных кавычек, который может сохранить перенос текста и формат отступов.

def strippedFirstNewline = '''line one
        line two
            line three
'''
println strippedFirstNewline
// 可以写成下面这种形式,可读性更好
def strippedFirstNewline2 = '''\
line one
    line two
line three
'''
println strippedFirstNewline2

персонаж

В Groovy нет явного литерального представления символов, есть три способа указать отображение

char c1 = 'A' // 声明类型
assert c1 instanceof Character

def c2 = 'B' as char // 用as关键字
assert c2 instanceof Character

def c3 = (char) 'C' // 强制类型转换
assert c3 instanceof Character

метод (функция)

Модификатор доступа по умолчанию для методов Groovy:public, возвращаемый тип метода не нужно объявлять, но нужно добавитьdefключевые слова. метод с возвращаемым значениемreturnМожно не указывать, по умолчанию возвращает результат последней строки кода, если используетсяreturnКлючевое слово возвращает указанное возвращаемое значение.

String method1() {
    return 'hello'
}
assert method1() == 'hello';

def method2() {
    return 'hello'
}
assert method2() == 'hello';

def method3() {
    'hello'
}
assert method3() == 'hello';

Тип параметра метода Groovy можно опустить, и по умолчанию используется тип объекта.

def add(int a, int b) {
    return a + b
}
//与上面的等价
def add(a, b) {
    a + b
}

Другие функции методов Groovy такие же, как в Java, например, поддержка перегрузки, параметры переменной длины (...) и т. д.

Закрытие

Groovy поддерживает замыкания. Синтаксис чем-то похож на лямбда-выражения. Короче говоря, это исполняемый блок кода или указатель на функцию. Замыкания в Groovygroovy.lang.ClosureЭкземпляры классов, которые позволяют назначать замыкания переменным или передавать их в качестве аргументов. Синтаксис для определения замыканий в Groovy так же прост, как показано ниже.

//闭包的参数为可选项
def closure = { [closureParameters -> ] statements }

Замыкания могут обращаться к внешним переменным, а методы (функции) — нет.

def str = 'hello'
def closure={
    println str
}
closure()//hello

Есть два способа вызвать замыкание: closure.call(параметр) или closure(параметр), при вызове можно опустить круглые скобки.

def closure = {
    param -> println param
}

closure('hello')
closure.call('hello')
closure 'hello'

Параметры замыкания являются необязательными и могут быть опущены, если параметры отсутствуют.->оператор.

def closure = {println 'hello'}
closure()

Несколько параметров разделяются запятыми, а типы параметров могут быть явно объявлены или опущены, как и методы.

def closure = { String x, int y ->                                
    println "hey ${x} the value is ${y}"
}

Если имеется только один параметр, определение параметра также можно опустить. Groovy предоставляет неявный параметрitзаменить его.

def closure = { it -> println it } 
//和上面是等价的
def closure = { println it }   
closure('hello')

Замыкания могут быть переданы как параметры, а круглые скобки могут быть опущены, если замыкание используется как единственный параметр или последний параметр метода.

def eachLine(lines, closure) {
    for (String line : lines) {
        closure(line)
    }
}

eachLine('a'..'z',{ println it }) 
//可省略括号,与上面等价
eachLine('a'..'z') { println it }

Lists

Groovy определяет List очень лаконично, используя квадратные скобки ([]), через запятую (,) для разделения элементов. Список в Groovy на самом делеjava.util.List, класс реализации по умолчанию используетjava.util.ArrayList.

def numbers = [1, 2, 3]         

assert numbers instanceof List  
assert numbers.class == java.util.ArrayList  
assert numbers.size() == 3

Arrays

Синтаксис определения массива в Groovy очень похож на синтаксис List. Разница в том, что определение массива должно указывать тип как тип массива. Вы можете определить тип напрямую или использовать определение определения, а затем указать его тип. через ключевое слово as.

String[] arrStr = ['Ananas', 'Banana', 'Kiwi'] //直接声明类型为数组类型  String[]

assert arrStr instanceof String[]    
assert !(arrStr instanceof List)

def numArr = [1, 2, 3] as int[]     //痛过as关键字指定类型为数组类型 int[] 

assert numArr instanceof int[]       
assert numArr.size() == 3

Maps

Groovy определяет Map очень лаконично: ключ и значение заключены в квадратные скобки, а ключ и значение разделены двоеточиями ([key:value]). Карта в Groovy на самом делеjava.util.Map, класс реализации по умолчанию используетjava.util.LinkedHashMap.

// key虽然没有加引号,不过Groovy会默认将其转换为字符串
def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF']

assert colors['red'] == '#FF0000' // 使用中括号访问
assert colors.green == '#00FF00' // 使用点表达式访问

colors['pink'] = '#FF00FF' // 使用中括号添加元素,相当于Java Map 的 put(key,value)方法
colors.yellow = '#FFFF00'// 使用点表达式添加元素
assert colors.pink == '#FF00FF'
assert colors['yellow'] == '#FFFF00'
assert colors instanceof java.util.LinkedHashMap // 默认使用LinkedHashMap类型

// Groovy Map的key默认语法不支持变量,这里的key时间上是字符串'keyVal'而不是keyVal变量的值'name'
def keyVal = 'name'
def persons = [keyVal: 'Guillaume'] 
assert !persons.containsKey('name')
assert persons.containsKey('keyVal')

//要使用变量作为key,需要使用括号
def keyVal = 'name'
def persons = [(keyVal): 'Guillaume'] 
assert persons.containsKey('name')
assert !persons.containsKey('keyVal')

Range

Доступно в Groovy..оператор для определения объекта диапазона, упрощая код для операций диапазона.

def range = 0..5
assert (0..5).collect() == [0, 1, 2, 3, 4, 5]
assert (0..<5).collect() == [0, 1, 2, 3, 4] // 相当于左闭右开区间
assert (0..5) instanceof List // Range实际上是List接口的实现
assert (0..5).size() == 6
assert ('a'..'d').collect() == ['a','b','c','d']//也可以是字符类型

//常见使用场景
for (x in 1..10) {
    println x
}

('a'..'z').each {
    println it
}

def age = 25;
switch (age) {
    case 0..17:
        println '未成年'
        break
    case 18..30:
        println '青年'
        break
    case 31..50:
        println '中年'
        break
    default:
        println '老年'
}

Распространенные сценарии использования

Grails

GrailsЭто высокопроизводительная универсальная среда веб-разработки, основанная на языке Groovy, построенная на Spring/Spring Boot и Hibernate. Это особенно подходит для небольших команд для гибкой разработки, и эффективность очень высока. Из-за затрат на производительность и обучение уровень проникновения относительно низок, и большинство компаний по-прежнему предпочитают выбирать Spring Boot в качестве среды разработки.

Gradle

GradleЭто инструмент для автоматизации сборки проектов, основанный на концепциях Apache Ant и Apache Maven. Он использует доменный язык (DSL) на основе Groovy для настройки сборки, отказывается от различных громоздких конфигураций на основе XML, в основном для приложений Java, и поддерживает загрузку зависимостей из хранилищ Maven. Сейчас все больше и больше проектов (в основном проектов Android) используют Gradle в качестве инструмента сборки проектов, и я верю, что Gradle постепенно заменит Maven в будущем, так же как Maven заменит Ant.

Соберите проект с помощью Maven

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.vs</groupId>
    <artifactId>com.vs.maven.gradle</artifactId>
    <version>1.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.6.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa
            </artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.25</version>
        </dependency>
    </dependencies>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Соберите проект с помощью Gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE")
    }
}
dependencies {
    compile("org.springframework.boot:spring-boot-starter-web") {
        exclude module: "spring-boot-starter-tomcat"
    }
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    testCompile("mysql:mysql-connector-java:5.1.25")
}

Пружинная поддержка

Динамические языки сценариев поддерживаются начиная с Spring 2.0 (Адрес этой части официальной документации Spring), который включает Groovy, Spring предоставляет<lang:groovy/>теги для определения Groovy Beans. Доступ к Groovy Bean можно получить черезscript-sourceСвойства загружают файлы сценариев, исходные файлы сценариев могут поступать из локальной или сетевой среды, и к ним можно получить доступ черезrefresh-check-delayИзменения кода в сценарии мониторинга свойств перезагружают компонент для реализации динамического компонента.

// from the file '/java/Calculator.java'
public interface Calculator {
    int add(int x, int y);
}

// from the file '/resources/CalculatorGroovyImpl.groovy'
class CalculatorGroovyImpl implements Calculator {
    int add(int x, int y) {
        x + y
    }
}
<-- from the file 'beans.xml' 省略 xmlns -->
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <lang:groovy id="calculator" script-source="classpath:CalculatorGroovyImpl.groovy" refresh-check-delay="1000"/>
</beans>
public class Tester {
    public static void main(String[] args) throws InterruptedException {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Calculator calculator = (Calculator)context.getBean("calculator");
        //尝试修改CalculatorGroovyImpl.groovy,将 x + y,修改为x * y。
        while (true){
            System.out.println(calculator.add(1, 1));
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

Начиная с версии Spring 4.0, Spring поддерживает использование Groovy DSL для определения конфигурации bean-компонентов.Подробнее см. в этом разделе официальной документации Spring..

beans {
    //beanName(type)  
    dataSource(BasicDataSource) {
        //注入属性
        driverClassName = "org.hsqldb.jdbcDriver"
        url = "jdbc:hsqldb:mem:grailsDB"
        username = "sa"
        password = ""
        settings = [mynew:"setting"]
    }
    sessionFactory(SessionFactory) {
       //注入属性,引用其他Bean
        dataSource = dataSource
    }
    myService(MyService) {
       //使用闭包定义嵌套的Bean
        nestedBean = { AnotherBean bean ->
            dataSource = dataSource
        }
    }
}
ApplicationContext context = new GenericGroovyApplicationContext("beans.groovy");
MyService myService = context.getBean(MyService.class);

Интеграция с Java

Groovy очень легко интегрируется в среду Java и использует его динамизм в качестве механизма правил, механизма процессов и динамической среды сценариев.Он очень подходит для использования в сценариях, которые не требуют частых выпусков, но часто изменяются. Существует несколько способов интеграции (вызова) кода Groovy в Java.

Eval

groovy.util.EvalКласс — это простейший класс, используемый для динамического выполнения кода Groovy во время выполнения.Он предоставляет несколько статических фабричных методов для использования, которые на самом деле являются инкапсуляцией GroovyShell.

//执行Groovy代码
Eval.me("println 'hello world'");
//绑定自定义参数
Object result = Eval.me("age", 22, "if(age < 18){'未成年'}else{'成年'}");
assertEquals(result, "成年");
//绑定一个名为 x 的参数的简单计算
assertEquals(Eval.x(4, "2*x"), 8);
//带有两个名为 x 与 y 的绑定参数的简单计算
assertEquals(Eval.xy(4, 5, "x*y"), 20);
//带有三个绑定参数(x、y 和 z)的简单计算
assertEquals(Eval.xyz(4, 5, 6, "x*y+z"), 26);
GroovyShell

groovy.lang.GroovyShellВ дополнение к выполнению кода Groovy он предоставляет более богатые функции, такие как привязка большего количества переменных, загрузка кода из файловой системы, сети и т. д.

GroovyShell shell = new GroovyShell();
//可以绑定更多变量
shell.setVariable("age",22);
//直接求值
shell.evaluate("if(age < 18){'未成年'}else{'成年'}");
//解析为脚本,延迟执行或者缓存起来
Script script = shell.parse("if(age < 18){'未成年'}else{'成年'}");
assertEquals(script.run(), "成年");
//可以从更多位置加载/执行脚本
//shell.evaluate(new File("script.groovy"));
//shell.evaluate(new URI("http://wwww.a.com/script.groovy"));
GroovyClassLoader

groovy.lang.GroovyClassLoaderПользовательский загрузчик классов, который может загружать код Groovy во время выполнения и создавать объекты класса.

 GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
 String scriptText = "class Hello { void hello() { println 'hello' } }";
 //将Groovy脚本解析为Class对象
 Class clazz = groovyClassLoader.parseClass(scriptText);
 //Class clazz = groovyClassLoader.parseClass(new File("script.groovy"));
 assertEquals(clazz.getName(),"Hello");
 clazz.getMethod("hello").invoke(clazz.newInstance());
GroovyScriptEngine

groovy.util.GroovyScriptEngineМожет обрабатывать динамическую компиляцию и загрузку любого кода Groovy, может загружать сценарии из единого места, а также может отслеживать изменения в сценариях и перезагружать их при изменении.

//script/groovy/hello.groovy
println "hello $name"
GroovyScriptEngine scriptEngine = new GroovyScriptEngine("script/groovy");
Binding binding = new Binding();
binding.setVariable("name", "groovy");
while (true){
    scriptEngine.run("hello.groovy", binding);
    TimeUnit.SECONDS.sleep(1);
}
//输出
hello groovy
hello groovy
....
//将hello.groovy内代码修改为println "hi $name", GroovyScriptEngine会重新进行加载
hi groovy
hi groovy
JSR 223 javax.script API

JSR-223 — это стандартный API для вызова языков сценариев в Java. Представленная начиная с Java 6, основная цель — предоставить унифицированную структуру для вызова нескольких языков сценариев в Java. JSR-223 поддерживает большинство популярных языков сценариев, таких как JavaScript, Scala, JRuby, Jython и Groovy.

ScriptEngine engine = new ScriptEngineManager().getEngineByName("groovy");
Bindings bindings = new SimpleBindings();
bindings.put("age", 22);
Object value = engine.eval("if(age < 18){'未成年'}else{'成年'}",bindings);
assertEquals(value,"成年");

//script/groovy/hello.groovy
//println "hello world"
engine.eval(new FileReader("script/groovy/hello.groovy"));
//hello world

Поскольку сам Groovy предоставляет более богатый механизм интеграции, если вы используете Groovy только как язык сценариев в приложении Java, может быть более подходящим использовать механизм интеграции, предоставляемый Groovy.

Интеграция с Java примерно описана выше, перед использованием рекомендуется прочитать:Общие ошибки в интеграции Groovy и Java

Ссылаться на