Groovy Série Três Java SpringBoot Integrar Groovy

 

Índice

I. Visão geral

1. Usando o Groovy em Java:

2. Use Java no Groovy:

3. Diferenças, vantagens e desvantagens de vários paradigmas

Java chama classes e métodos Groovy:

Groovy chama classes e métodos Java:

 Execute scripts Groovy usando GroovyShell:

Carregue e execute scripts Groovy usando GroovyClassLoader:

Dois, combate real

O primeiro passo é integrar com SpringBoot e introduzir dependências

A segunda etapa, escreva um script bacana

A terceira etapa é criar uma classe de teste e usar o GroovyShell para demonstrar

A quarta etapa, veja os resultados em execução

A quinta etapa é iniciar o SpringBoot e obter o Bean no contêiner SpringBoot por meio do SpringContextUtil no script Groovy

Etapa 6. Crie o Bean no contêiner

Etapa 7. Código de acesso

A oitava etapa, iniciar, teste de interface

3. Otimização

A primeira etapa é criar um script Groovy e implementá-lo usando GroovyClassLoader

A segunda etapa é criar um Bean de chamada Groovy

A terceira etapa é criar um GroovyClassLoader para carregar a classe

A quarta etapa, crie uma API de solicitação


Nos dois últimos artigos, estudamos sistematicamente a gramática básica e o GDK do Groovy. Neste artigo, aprenderemos como integrar Groovy e Java e como integrá-lo ao projeto SpringBoot. Há uma boa integração entre Groovy e Java, e você pode chamar e usar o código e os recursos um do outro. Através da integração de Groovy e Java, as vantagens de ambos podem ser totalmente utilizadas, tornando o desenvolvimento mais flexível e eficiente.

I. Visão geral

1. Usando o Groovy em Java:

  1. Adicione a dependência Groovy ao projeto Java.
  2. Use classes e scripts Groovy em código Java. O código Groovy pode ser executado diretamente em Java e você pode chamar métodos de classes Groovy, acessar suas propriedades e assim por diante. Os scripts Groovy podem ser executados usando GroovyShell ou GroovyClassLoader.

2. Use Java no Groovy:

  1. Groovy suporta Java nativamente, você pode usar classes Java diretamente, chamar métodos Java e assim por diante. O código Groovy pode ser misturado com o código Java.
  2. Ao usar classes Java no código Groovy, nenhuma importação adicional é necessária, basta usá-las diretamente.
  3. O Groovy também fornece uma sintaxe mais concisa e recursos mais poderosos, como encerramentos, métodos de extensão, tipos dinâmicos etc., que facilitam a escrita do código.

Para conseguir uma melhor integração, você pode prestar atenção aos seguintes pontos:

  • Use a mesma ferramenta de gerenciamento de dependência para garantir que os projetos Java e Groovy usem as mesmas versões de dependências.
  • Certifique-se de que as classes Java sejam compiladas e que seus arquivos bytecode gerados e o código Groovy sejam colocados no mesmo caminho de classe para que possam acessar uns aos outros.
  • Ao executar scripts Groovy usando GroovyShell ou GroovyClassLoader, inclua o caminho das classes Java no caminho da classe para que o código Groovy possa acessar as classes Java.

3. Diferenças, vantagens e desvantagens de vários paradigmas

Existem muitas formas de se conseguir a integração entre Groovy e Java, abaixo irei descrever algumas formas comuns, suas diferenças, vantagens e desvantagens.

Java chama classes e métodos Groovy:

  • Descrição: Java pode acessar diretamente classes e métodos Groovy por meio do caminho de classe e tratar o código Groovy como parte do código Java. Você pode chamar métodos de classes Groovy, acessar suas propriedades, etc.
  • Diferente: Java pode chamar classes e métodos Groovy perfeitamente, assim como chamar código Java.
  • Vantagens: Simples e direto, é muito conveniente escrever códigos mistos de Groovy e Java.
  • Desvantagens: Para recursos exclusivos do Groovy, como fechamentos, digitação dinâmica etc., Java pode não entendê-lo completamente.

Groovy chama classes e métodos Java:

  • Descrição: Groovy suporta Java naturalmente, você pode usar classes Java diretamente, chamar métodos Java, etc. O código Groovy pode ser escrito misturado com código Java sem importações adicionais.
  • Diferença: A integração de Groovy e Java é muito harmoniosa, podendo importar classes Java automaticamente e usar diretamente a sintaxe Java.
  • Vantagens: integração perfeita, pode fazer pleno uso do ecossistema Java e das bibliotecas existentes.
  • Desvantagens: Groovy pode ser mais "dinâmico" que Java em alguns aspectos, o que significa que pode haver perdas de desempenho e segurança de tipo em alguns casos.

 Execute scripts Groovy usando GroovyShell:

  • Descrição: Use GroovyShell para executar blocos de código de script Groovy em código Java. Os scripts Groovy podem ser carregados e executados dinamicamente.
  • Diferente: Através do método de avaliação do GroovyShell, o código de script Groovy dinâmico pode ser executado em Java.
  • Vantagens: Pode executar scripts Groovy dinamicamente em tempo de execução, o que é altamente flexível, conveniente e rápido.
  • Desvantagens: Executar scripts dinamicamente pode ter um certo impacto no desempenho e requer verificação de sintaxe adicional.

Carregue e execute scripts Groovy usando GroovyClassLoader:

  • Descrição: Carregue e execute scripts Groovy por meio de GroovyClassLoader em Java, o que pode obter uma execução de script mais flexível.
  • Diferente: ao carregar o script Groovy por meio do GroovyClassLoader, o objeto Class correspondente pode ser obtido, instanciado e chamado conforme necessário.
  • Vantagens: Os scripts Groovy podem ser carregados e executados de forma flexível e interagir com o código Java. Desvantagens: Comparado com o GroovyShell, o uso do GroovyClassLoader requer mais código para implementar o carregamento e a execução.

Para resumir, diferentes métodos de integração Groovy e Java têm diferentes vantagens e desvantagens. Podemos escolher o método apropriado de acordo com as necessidades específicas. Usar Java para chamar classes e métodos Groovy e Groovy para chamar classes e métodos Java é a forma mais direta e perfeita de integração. Usar GroovyShell ou GroovyClassLoader para executar scripts Groovy é mais flexível e adequado para cenários que requerem execução dinâmica de scripts.

Dois, combate real

Em seguida, vamos apresentar como o SpringBoot integra os scripts Groovy e os aplica ao desenvolvimento real.

O primeiro passo é integrar com SpringBoot e introduzir dependências

<dependency>
   <groupId>org.codehaus.groovy</groupId>
   <artifactId>groovy-all</artifactId>
   <version>3.0.17</version>
   <type>pom</type>
</dependency>

A segunda etapa, escreva um script bacana

package script

import com.example.groovy.GroovyInvokeJavaDemo
import com.example.groovy.groovyshell.ShellGroovyDTO
import com.example.groovy.utils.SpringContextUtil

/**
 * @Author: lly
 * @Date: 2023/7/1
 */

def helloWord() {
    return "hello groovy"
}

helloWord()

def cal(int a, int b) {
    ShellGroovyDTO dto = new ShellGroovyDTO()
    dto.setA(a)
    dto.setB(b)
    if (b > 0) {
        dto.setNum(a + b)
    } else {
        dto.setNum(a)
    }
    return dto
};

cal(a, b)

/** 定义静态变量 **/
class Globals {
    static String PARAM1 = "静态变量"
    static int[] arrayList = [1, 2]
}

def groovyInvokeJavaMethod(int a, int b) {
    GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean("groovyInvokeJavaDemo")
//    return groovyInvokeJavaDemo.groovyInvokeJava();

    return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b);
}

groovyInvokeJavaMethod(a, b)

A terceira etapa é criar uma classe de teste e usar o GroovyShell para demonstrar

* // Cria uma instância do GroovyShell

* // Cria um objeto Binding para passar parâmetros e receber resultados

* // Definindo parâmetros

* // Executa o script Groovy

* // Obtém o resultado

package com.example.groovy.groovyshell;

import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;

/**
 * @Author: lly
 * @Date: 2023/7/1
 * <p>
 * 下面这段测试类包含两个,一个是有参数的调用,一个是无参数的调用
 * // 创建GroovyShell实例
 * // 创建Binding对象,用于传递参数和接收结果
 * // 设置参数
 * // 执行Groovy脚本
 * // 获取结果
 */
public class GroovyShellApp {
    /**
     * GroovyShell 无参数 demo
     **/
    public static void main(String[] args) {
        String groovyStr = "package script\n" +
                "\n" +
                "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
                "\n" +
                "/**\n" +
                " * @Author: lly\n" +
                " * @Date: 2023/7/1\n" +
                " */\n" +
                "\n" +
                "def helloWord() {\n" +
                "    return \"hello groovy\"\n" +
                "}\n" +
                "\n" +
                "helloWord()\n" +
                "\n" +
                "def cal(int a, int b) {\n" +
                "    ShellGroovyDTO dto = new ShellGroovyDTO()\n" +
                "    dto.setA(a)\n" +
                "    dto.setB(b)\n" +
                "    if (b > 0) {\n" +
                "        dto.setNum(a + b)\n" +
                "    } else {\n" +
                "        dto.setNum(a)\n" +
                "    }\n" +
                "    return dto\n" +
                "};\n" +
                "\n" +
                "cal(a , b)";

        // 创建GroovyShell实例
        GroovyShell shell = new GroovyShell();
        Script script = shell.parse(groovyStr);
        Object helloWord = script.invokeMethod("helloWord", null);
        System.out.println(helloWord);

    }

    /** GroovyShell 有参数 demo **/
//    public static void main(String[] args) {
//
//        String groovyStr = "package script\n" +
//                "\n" +
//                "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
//                "\n" +
//                "/**\n" +
//                " * @Author: lly\n" +
//                " * @Date: 2023/7/1\n" +
//                " */\n" +
//                "def cal(int a, int b) {\n" +
//                "    ShellGroovyDTO dto = new ShellGroovyDTO()\n" +
//                "    dto.setA(a)\n" +
//                "    dto.setB(b)\n" +
//                "    if (b > 0) {\n" +
//                "        dto.setNum(a + b)\n" +
//                "    } else {\n" +
//                "        dto.setNum(a)\n" +
//                "    }\n" +
//                "    return dto\n" +
//                "};\n" +
//                "\n" +
//                "cal(a, b)";
//
//        // 创建Binding对象,用于传递参数和接收结果
//        Binding binding = new Binding();
//
//        // 创建GroovyShell实例
//        GroovyShell shell = new GroovyShell(binding);
//
//
//        // 设置参数
//        binding.setVariable("a", 10);
//        binding.setVariable("b", 20);
//
//        // 执行Groovy脚本
//        Object result = shell.evaluate(groovyStr);
//
//        // 获取结果
//        ShellGroovyDTO dto = (ShellGroovyDTO) result;
//        System.out.println(dto);
//    }
}

package com.example.groovy.groovyshell;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author: lly
 * @Date: 2023/7/1
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ShellGroovyDTO {
    private Integer a;
    private Integer b;
    private Integer num;

}

A quarta etapa, veja os resultados em execução

A quinta etapa é iniciar o SpringBoot e obter o Bean no contêiner SpringBoot por meio do SpringContextUtil no script Groovy

As etapas acima são para chamar o Groovy em código Java puro. Na verdade, no processo de desenvolvimento, geralmente intermodulamos o código Groovy e Java. A seguir, vamos ver como obter o Bean no contêiner SpringBoot por meio do SpringContextUtil no Groovy e chamar o destino. método.

package com.example.groovy.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

/**
 * @Author: lly
 * @Date: 2023/7/2
 */
@Service
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}

Etapa 6. Crie o Bean no contêiner

Criamos um bean "GroovyInvokeJavaDemo" e o entregamos ao Spring para gerenciamento. Existem dois métodos de destino, um requer parâmetros e o outro não requer parâmetros.Os parâmetros necessários quando chamamos o Groovy por meio do Java são passados ​​quando os métodos Java são chamados no Groovy.

package com.example.groovy;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: lly
 * @Date: 2023/7/2
 */
@Service
@Slf4j
public class GroovyInvokeJavaDemo {

    public String groovyInvokeJava() {
        List<String> lits = new ArrayList<>();
        log.info("this is SpringBoot class, groovy script invoke this method ...");
        return "this is SpringBoot class, groovy script invoke this method ...";
    }

    public String groovyInvokeJavaParam(int a, int b) {
        List<String> lits = new ArrayList<>();
        log.info("this is SpringBoot class, groovy script invoke this method ,param is a:{}, b:{}", a, b);
        return "this is SpringBoot class, groovy script invoke this method , a:" + a + ", b:" + b;
    }
}

Etapa 7. Código de acesso

package com.example.groovy;

import com.example.groovy.classloader.GroovyClassLoaderRule;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @Author: lly
 * @Date: 2023/7/2
 */
@RestController
@RequestMapping("/groovy")
public class GroovyInvokeJavaSpringController {

    @Resource
    private GroovyClassLoaderRule groovyClassLoaderRule;

    @RequestMapping("/groovy-shell/spring")
    public String groovyInvokeJavaMethodTest() {
        String groovyStr = "package script\n" +
                "\n" +
                "import com.example.groovy.GroovyInvokeJavaDemo\n" +
                "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
                "import com.example.groovy.utils.SpringContextUtil\n" +
                "\n" +
                "/**\n" +
                " * @Author: lly\n" +
                " * @Date: 2023/7/1\n" +
                " */\n" +
                "\n" +
                "def helloWord() {\n" +
                "    return \"hello groovy\"\n" +
                "}\n" +
                "\n" +
                "helloWord()\n" +
                "\n" +
                "def cal(int a, int b) {\n" +
                "    ShellGroovyDTO dto = new ShellGroovyDTO()\n" +
                "    dto.setA(a)\n" +
                "    dto.setB(b)\n" +
                "    if (b > 0) {\n" +
                "        dto.setNum(a + b)\n" +
                "    } else {\n" +
                "        dto.setNum(a)\n" +
                "    }\n" +
                "    return dto\n" +
                "};\n" +
                "\n" +
                "cal(a , b)\n" +
                "\n" +
                "/** 定义静态变量 **/\n" +
                "class Globals {\n" +
                "    static String PARAM1 = \"静态变量\"\n" +
                "    static int[] arrayList = [1, 2]\n" +
                "}\n" +
                "\n" +
                "def groovyInvokeJavaMethod(int a, int b) {\n" +
                "    GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean(\"groovyInvokeJavaDemo\")\n" +
                "//    return groovyInvokeJavaDemo.groovyInvokeJava();\n" +
                "    return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b);\n" +
                "}\n" +
                "\n" +
                "groovyInvokeJavaMethod(a, b)";

        Binding binding = new Binding();
        binding.setVariable("a", 100);
        binding.setVariable("b", 100);

        GroovyShell groovyShell = new GroovyShell(binding);

        Object evaluate = groovyShell.evaluate(groovyStr);

        groovyShell.getClassLoader().clearCache();

        return (String) evaluate;

    }

}

A oitava etapa, iniciar, teste de interface

Visite " http://localhost:8080/groovy/groovy-shell/spring " para ver o efeito.

3. Otimização

Acima integramos Groovy em Java, mas o código acima tem um grande problema, que se reflete principalmente em dois aspectos:

O primeiro aspecto: Através da quinta etapa, podemos ver que o objeto contêiner SpringBoot pode ser obtido no Groovy, e todas as coisas no contêiner podem ser obtidas obtendo o objeto contêiner. Embora isso seja muito conveniente e flexível, é muito perigoso. Se o controle de permissão não for bem feito, o script Groovy se tornará a arma mais poderosa para atacar seu sistema!

O segundo aspecto: Se o script Groovy não for bem usado, causará OOM e, eventualmente, o servidor cairá. Toda vez que esse método é chamado, são criadas instâncias de GroovyShell, Script, etc. Conforme o número de chamadas aumenta, OOM inevitavelmente ocorrerá.

A solução é usar a função clearCache() do GroovyClassLoader para destruir GroovyShell, Script e outras instâncias após a chamada, mas na verdade isso não é suficiente. O motivo do OOM não é apenas muitas instâncias de GroovyShell e Script. Após consultar o data, sabemos que se o script O código Java também criar um objeto ou uma nova instância, mesmo que o GroovyShell seja destruído, o objeto no script não será destruído. Portanto, o código Groovy é melhor para usar o gerenciamento de cache.

A primeira etapa é criar um script Groovy e implementá-lo usando GroovyClassLoader

GroovyClassLoad_1.groovy

package script

import com.example.groovy.GroovyInvokeJavaDemo
import com.example.groovy.groovyshell.ShellGroovyDTO
import com.example.groovy.utils.SpringContextUtil

/**
 * @Author: lly
 * @Date: 2023/7/1
 */

def groovyInvokeJavaMethod(int a, int b) {
    GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean("groovyInvokeJavaDemo")
//    return groovyInvokeJavaDemo.groovyInvokeJava();

    return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b)
}

groovyInvokeJavaMethod(a, b)

GroovyClassLoad_2.groovy

package script

import com.example.groovy.GroovyInvokeJavaDemo
import com.example.groovy.groovyshell.ShellGroovyDTO
import com.example.groovy.utils.SpringContextUtil

/**
 * @Author: lly
 * @Date: 2023/7/1
 */

def groovyInvokeJavaMethod(int a, int b) {
    GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean("groovyInvokeJavaDemo")
//    return groovyInvokeJavaDemo.groovyInvokeJava();

    return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b)
}

groovyInvokeJavaMethod(a, b)

A segunda etapa é criar um Bean de chamada Groovy

package com.example.groovy;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: lly
 * @Date: 2023/7/2
 */
@Service
@Slf4j
public class GroovyInvokeJavaDemo {

    public String groovyInvokeJava() {
        List<String> lits = new ArrayList<>();
        log.info("this is SpringBoot class, groovy script invoke this method ...");
        return "this is SpringBoot class, groovy script invoke this method ...";
    }

    public String groovyInvokeJavaParam(int a, int b) {
        List<String> lits = new ArrayList<>();
        log.info("this is SpringBoot class, groovy script invoke this method ,param is a:{}, b:{}", a, b);
        return "this is SpringBoot class, groovy script invoke this method , a:" + a + ", b:" + b;
    }
}

A terceira etapa é criar um GroovyClassLoader para carregar a classe

package com.example.groovy.classloader;

/**
 * @Author: lly
 * @Date: 2023/7/1
 *
 * 定义 Groovy 执行的接口
 */
public interface GroovyClassLoaderRule {

    String run();
}
package com.example.groovy.classloader;

import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import groovy.lang.Script;
import lombok.extern.slf4j.Slf4j;
import org.apache.groovy.parser.antlr4.util.StringUtils;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: lly
 * @Date: 2023/7/1
 */
@Slf4j
@Service
public class GroovyClassLoaderRuleImpl implements GroovyClassLoaderRule {

    /**
     * 脚本容器 :缓存Script,避免创建太多
     **/
    private static final Map<String, GroovyObject> SCRIPT_MAP = new HashMap<>();

    private static final GroovyClassLoader CLASS_LOADER = new GroovyClassLoader();

    public static GroovyObject loadScript(String key, String rule) {
        if (SCRIPT_MAP.containsKey(key)) {
            return SCRIPT_MAP.get(key);
        }
        GroovyObject groovyObject = loadScript(rule);
        SCRIPT_MAP.put(key, groovyObject);
        return groovyObject;
    }

    public static GroovyObject loadScript(String rule) {
        if (StringUtils.isEmpty(rule)) {
            return null;
        }
        try {
            Class ruleClazz = CLASS_LOADER.parseClass(rule);
            if (ruleClazz != null) {
                log.info("load rule:" + rule + " success!");
                GroovyObject groovyObject = (GroovyObject) ruleClazz.newInstance();
                return groovyObject;
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            CLASS_LOADER.clearCache();
        }

        log.error("load rule error, can not load Script");
        return null;
    }


    @Override
    public String run() {
        // 业务逻辑执行,方便配置
        String groovyClassLoader1 = "package script\n" +
                "\n" +
                "import com.example.groovy.GroovyInvokeJavaDemo\n" +
                "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
                "import com.example.groovy.utils.SpringContextUtil\n" +
                "\n" +
                "/**\n" +
                " * @Author: lly\n" +
                " * @Date: 2023/7/1\n" +
                " */\n" +
                "\n" +
                "def groovyInvokeJavaMethod(int a, int b) {\n" +
                "    GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean(\"groovyInvokeJavaDemo\")\n" +
                "//    return groovyInvokeJavaDemo.groovyInvokeJava();\n" +
                "\n" +
                "    return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b)\n" +
                "}\n" +
                "\n" +
                "groovyInvokeJavaMethod(a, b)";

        String groovyClassLoader2 = "package script\n" +
                "\n" +
                "import com.example.groovy.GroovyInvokeJavaDemo\n" +
                "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
                "import com.example.groovy.utils.SpringContextUtil\n" +
                "\n" +
                "/**\n" +
                " * @Author: lly\n" +
                " * @Date: 2023/7/1\n" +
                " */\n" +
                "\n" +
                "def groovyInvokeJavaMethod(int a, int b) {\n" +
                "    GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean(\"groovyInvokeJavaDemo\")\n" +
                "//    return groovyInvokeJavaDemo.groovyInvokeJava();\n" +
                "\n" +
                "    return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b)\n" +
                "}\n" +
                "\n" +
                "groovyInvokeJavaMethod(a, b)";

        Binding binding = new Binding();
        binding.setVariable("a", 300);
        binding.setVariable("b", 400);

//        Script classLoader1 = loadScript("groovyClassLoader1", groovyClassLoader1, binding);
        GroovyObject groovyObject = loadScript("groovyClassLoader2", groovyClassLoader2);

        Object groovyInvokeJavaMethod = groovyObject.invokeMethod("groovyInvokeJavaMethod", new Object[]{100, 200});

        return (String) groovyInvokeJavaMethod;
    }
}

A quarta etapa, crie uma API de solicitação


@RequestMapping("/groovy-class-loader/spring")
public String groovyClassLoaderRuleTest() {
    String result = groovyClassLoaderRule.run();
    return result;

}

A quinta etapa, iniciar a verificação

Neste ponto, nossa série Groovy acabou. Se você precisar do código, pode visitar meu site gitHub para obtê-lo ou deixar uma mensagem. Enviarei uma mensagem privada, esperando ajudá-lo.

https://github.com/576403061lly/groovy

Acho que você gosta

Origin blog.csdn.net/lly576403061/article/details/131505699
Recomendado
Clasificación