Groovy系列三 Java SpringBoot 整合 Groovy

左手的ㄟ右手 2024-03-17 13:57 175阅读 0赞

目录

一、概述

一、在Java中使用Groovy:

二、在Groovy中使用Java:

三、几种范式的不同、优缺点

Java调用Groovy的类和方法:

Groovy调用Java的类和方法:

使用GroovyShell执行Groovy脚本:

使用GroovyClassLoader加载和执行Groovy脚本:

二、实战

第一步、与SpringBoot集成,引入依赖

第二步、编写groovy脚本

第三步、创建测试类使用GroovyShell演示

第四步、查看运行结果

第五步、启动SpringBoot,在Groovy脚本中通过SpringContextUtil获取SpringBoot容器中的Bean

第六步、创建容器中的Bean

第七步、访问代码

第八步、启动、接口测试

三、优化

第一步、创建Groovy脚本,使用GroovyClassLoader实现

第二步、创建Groovy调用Bean

第三步、创建GroovyClassLoader加载类

第四步、创建请求API


34206a7421b5466ab08a13cda41a5a49.png

上两篇我们系统的学习了Groovy的基础语法和GDK,本篇咱们学习如何将Groovy和Java集成,并且学习集成到SpringBoot项目中。Groovy和Java之间有很好的集成,可以相互调用和使用对方的代码和特性。通过Groovy和Java的集成,可以充分发挥两者的优势,让开发更加灵活和高效。

一、概述

一、在Java中使用Groovy:

  1. 添加Groovy的依赖到Java项目中。
  2. 在Java代码中使用Groovy的类和脚本。Groovy代码可以直接在Java中执行,可以调用Groovy类的方法、访问其属性等。可以使用GroovyShell或GroovyClassLoader来执行Groovy脚本。

二、在Groovy中使用Java:

  1. Groovy天生支持Java,可以直接使用Java类、调用Java方法等。Groovy代码可以与Java代码混合编写。
  2. 在Groovy代码中使用Java类时,不需要额外的导入,直接使用即可。
  3. Groovy还提供了更简洁的语法和更强大的特性,例如闭包、扩展方法、动态类型等,可以更方便地编写代码。

为了实现更好的集成,可以注意以下几点:

  • 使用相同的依赖管理工具,以确保Java和Groovy项目使用的是相同的版本依赖。
  • 确保Java类被编译并将其生成的字节码文件和Groovy代码放在相同的classpath下,以便彼此访问。
  • 在使用GroovyShell或GroovyClassLoader执行Groovy脚本时,将Java类的路径包含在class path中,以便Groovy代码可以访问Java类。

三、几种范式的不同、优缺点

在Groovy和Java之间实现集成有多种方式,下面我会描述其中几种常见的方式,以及它们的不同、优缺点。

Java调用Groovy的类和方法:

  • 描述:Java可以直接通过类路径访问Groovy的类和方法,将Groovy代码视为Java代码的一部分。可以调用Groovy类的方法、访问其属性等。
  • 不同:Java可以无缝地调用Groovy类和方法,就像调用Java代码一样。
  • 优点:简单直接,Groovy与Java代码混合编写非常方便。
  • 缺点:对于Groovy独有的特性,如闭包、动态类型等,Java可能无法完全理解。

Groovy调用Java的类和方法:

  • 描述:Groovy天生支持Java,可以直接使用Java类、调用Java方法等。Groovy代码可以与Java代码混合编写,无需额外导入。
  • 不同:Groovy与Java的集成非常融洽,可以自动导入Java类,直接使用Java的语法。
  • 优点:无缝集成,可以充分利用Java的生态系统和已有的库。
  • 缺点:Groovy在某些方面可能比Java更“动态”,这意味着在一些情况下可能会有性能和类型安全性的损失。

使用GroovyShell执行Groovy脚本:

  • 描述:在Java代码中使用GroovyShell执行Groovy脚本代码块。可以动态加载和执行Groovy脚本。
  • 不同:通过GroovyShell的evaluate方法,可以在Java中执行动态的Groovy脚本代码。
  • 优点:能够在运行时动态执行Groovy脚本,灵活性高,方便快捷。
  • 缺点:动态执行脚本可能会带来一定的性能影响,并且需要额外的语法检查。

使用GroovyClassLoader加载和执行Groovy脚本:

  • 描述:在Java中通过GroovyClassLoader加载和执行Groovy脚本,可以实现更灵活的脚本执行。
  • 不同:通过GroovyClassLoader加载Groovy脚本,可以获得对应的Class对象,并根据需要进行实例化和调用。
  • 优点:可以灵活地加载和执行Groovy脚本,并与Java代码进行交互。缺点:相对于GroovyShell,使用GroovyClassLoader需要更多的代码来实现加载和执行。

综上所述,不同的Groovy和Java集成方式具有不同的优缺点。我们可以根据具体需求选择合适的方式。使用Java调用Groovy类和方法以及Groovy调用Java类和方法是最直接、无缝的集成方式。而使用GroovyShell或GroovyClassLoader执行Groovy脚本则更灵活,适用于需要动态执行脚本的场景。

二、实战

那么接下来介绍SpringBoot如何集成Groovy脚本,并应用到实际开发中。

第一步、与SpringBoot集成,引入依赖

  1. <dependency>
  2. <groupId>org.codehaus.groovy</groupId>
  3. <artifactId>groovy-all</artifactId>
  4. <version>3.0.17</version>
  5. <type>pom</type>
  6. </dependency>

第二步、编写groovy脚本

  1. package script
  2. import com.example.groovy.GroovyInvokeJavaDemo
  3. import com.example.groovy.groovyshell.ShellGroovyDTO
  4. import com.example.groovy.utils.SpringContextUtil
  5. /**
  6. * @Author: lly
  7. * @Date: 2023/7/1
  8. */
  9. def helloWord() {
  10. return "hello groovy"
  11. }
  12. helloWord()
  13. def cal(int a, int b) {
  14. ShellGroovyDTO dto = new ShellGroovyDTO()
  15. dto.setA(a)
  16. dto.setB(b)
  17. if (b > 0) {
  18. dto.setNum(a + b)
  19. } else {
  20. dto.setNum(a)
  21. }
  22. return dto
  23. };
  24. cal(a, b)
  25. /** 定义静态变量 **/
  26. class Globals {
  27. static String PARAM1 = "静态变量"
  28. static int[] arrayList = [1, 2]
  29. }
  30. def groovyInvokeJavaMethod(int a, int b) {
  31. GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean("groovyInvokeJavaDemo")
  32. // return groovyInvokeJavaDemo.groovyInvokeJava();
  33. return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b);
  34. }
  35. groovyInvokeJavaMethod(a, b)

第三步、创建测试类使用GroovyShell演示

* // 创建GroovyShell实例

* // 创建Binding对象,用于传递参数和接收结果

* // 设置参数

* // 执行Groovy脚本

* // 获取结果

  1. package com.example.groovy.groovyshell;
  2. import groovy.lang.Binding;
  3. import groovy.lang.GroovyShell;
  4. import groovy.lang.Script;
  5. /**
  6. * @Author: lly
  7. * @Date: 2023/7/1
  8. * <p>
  9. * 下面这段测试类包含两个,一个是有参数的调用,一个是无参数的调用
  10. * // 创建GroovyShell实例
  11. * // 创建Binding对象,用于传递参数和接收结果
  12. * // 设置参数
  13. * // 执行Groovy脚本
  14. * // 获取结果
  15. */
  16. public class GroovyShellApp {
  17. /**
  18. * GroovyShell 无参数 demo
  19. **/
  20. public static void main(String[] args) {
  21. String groovyStr = "package script\n" +
  22. "\n" +
  23. "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
  24. "\n" +
  25. "/**\n" +
  26. " * @Author: lly\n" +
  27. " * @Date: 2023/7/1\n" +
  28. " */\n" +
  29. "\n" +
  30. "def helloWord() {\n" +
  31. " return \"hello groovy\"\n" +
  32. "}\n" +
  33. "\n" +
  34. "helloWord()\n" +
  35. "\n" +
  36. "def cal(int a, int b) {\n" +
  37. " ShellGroovyDTO dto = new ShellGroovyDTO()\n" +
  38. " dto.setA(a)\n" +
  39. " dto.setB(b)\n" +
  40. " if (b > 0) {\n" +
  41. " dto.setNum(a + b)\n" +
  42. " } else {\n" +
  43. " dto.setNum(a)\n" +
  44. " }\n" +
  45. " return dto\n" +
  46. "};\n" +
  47. "\n" +
  48. "cal(a , b)";
  49. // 创建GroovyShell实例
  50. GroovyShell shell = new GroovyShell();
  51. Script script = shell.parse(groovyStr);
  52. Object helloWord = script.invokeMethod("helloWord", null);
  53. System.out.println(helloWord);
  54. }
  55. /** GroovyShell 有参数 demo **/
  56. // public static void main(String[] args) {
  57. //
  58. // String groovyStr = "package script\n" +
  59. // "\n" +
  60. // "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
  61. // "\n" +
  62. // "/**\n" +
  63. // " * @Author: lly\n" +
  64. // " * @Date: 2023/7/1\n" +
  65. // " */\n" +
  66. // "def cal(int a, int b) {\n" +
  67. // " ShellGroovyDTO dto = new ShellGroovyDTO()\n" +
  68. // " dto.setA(a)\n" +
  69. // " dto.setB(b)\n" +
  70. // " if (b > 0) {\n" +
  71. // " dto.setNum(a + b)\n" +
  72. // " } else {\n" +
  73. // " dto.setNum(a)\n" +
  74. // " }\n" +
  75. // " return dto\n" +
  76. // "};\n" +
  77. // "\n" +
  78. // "cal(a, b)";
  79. //
  80. // // 创建Binding对象,用于传递参数和接收结果
  81. // Binding binding = new Binding();
  82. //
  83. // // 创建GroovyShell实例
  84. // GroovyShell shell = new GroovyShell(binding);
  85. //
  86. //
  87. // // 设置参数
  88. // binding.setVariable("a", 10);
  89. // binding.setVariable("b", 20);
  90. //
  91. // // 执行Groovy脚本
  92. // Object result = shell.evaluate(groovyStr);
  93. //
  94. // // 获取结果
  95. // ShellGroovyDTO dto = (ShellGroovyDTO) result;
  96. // System.out.println(dto);
  97. // }
  98. }
  99. package com.example.groovy.groovyshell;
  100. import lombok.AllArgsConstructor;
  101. import lombok.Builder;
  102. import lombok.Data;
  103. import lombok.NoArgsConstructor;
  104. /**
  105. * @Author: lly
  106. * @Date: 2023/7/1
  107. */
  108. @Data
  109. @AllArgsConstructor
  110. @NoArgsConstructor
  111. @Builder
  112. public class ShellGroovyDTO {
  113. private Integer a;
  114. private Integer b;
  115. private Integer num;
  116. }

第四步、查看运行结果

5d5ac897e5374bc7a72b8b9604a6a869.png

第五步、启动SpringBoot,在Groovy脚本中通过SpringContextUtil获取SpringBoot容器中的Bean

上面几步都是纯Java代码中调用Groovy,其实在开发的过程中,我们通常会Groovy和Java代码互调,接下来咱们看看如何使实现Groovy中通过SpringContextUtil获取SpringBoot容器中的Bean并且调用目标方法。

  1. package com.example.groovy.utils;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.ApplicationContextAware;
  5. import org.springframework.stereotype.Service;
  6. /**
  7. * @Author: lly
  8. * @Date: 2023/7/2
  9. */
  10. @Service
  11. public class SpringContextUtil implements ApplicationContextAware {
  12. private static ApplicationContext applicationContext;
  13. @Override
  14. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  15. SpringContextUtil.applicationContext = applicationContext;
  16. }
  17. public static ApplicationContext getApplicationContext() {
  18. return applicationContext;
  19. }
  20. /**
  21. * 通过name获取 Bean.
  22. *
  23. * @param name
  24. * @return
  25. */
  26. public static Object getBean(String name) {
  27. return getApplicationContext().getBean(name);
  28. }
  29. /**
  30. * 通过class获取Bean.
  31. *
  32. * @param clazz
  33. * @param <T>
  34. * @return
  35. */
  36. public static <T> T getBean(Class<T> clazz) {
  37. return getApplicationContext().getBean(clazz);
  38. }
  39. /**
  40. * 通过name,以及Clazz返回指定的Bean
  41. *
  42. * @param name
  43. * @param clazz
  44. * @param <T>
  45. * @return
  46. */
  47. public static <T> T getBean(String name, Class<T> clazz) {
  48. return getApplicationContext().getBean(name, clazz);
  49. }
  50. }

第六步、创建容器中的Bean

咱们创建一个“GroovyInvokeJavaDemo“bean,并交给Spring管理。其中有两个目标方法,一个是需要参数的,一个不需要参数,需要参数的咱们通过Java调用Groovy的时候传入的参数在Groovy中调用Java方法的时候传入。

  1. package com.example.groovy;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.stereotype.Service;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. /**
  7. * @Author: lly
  8. * @Date: 2023/7/2
  9. */
  10. @Service
  11. @Slf4j
  12. public class GroovyInvokeJavaDemo {
  13. public String groovyInvokeJava() {
  14. List<String> lits = new ArrayList<>();
  15. log.info("this is SpringBoot class, groovy script invoke this method ...");
  16. return "this is SpringBoot class, groovy script invoke this method ...";
  17. }
  18. public String groovyInvokeJavaParam(int a, int b) {
  19. List<String> lits = new ArrayList<>();
  20. log.info("this is SpringBoot class, groovy script invoke this method ,param is a:{}, b:{}", a, b);
  21. return "this is SpringBoot class, groovy script invoke this method , a:" + a + ", b:" + b;
  22. }
  23. }

第七步、访问代码

  1. package com.example.groovy;
  2. import com.example.groovy.classloader.GroovyClassLoaderRule;
  3. import groovy.lang.Binding;
  4. import groovy.lang.GroovyShell;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import javax.annotation.Resource;
  8. /**
  9. * @Author: lly
  10. * @Date: 2023/7/2
  11. */
  12. @RestController
  13. @RequestMapping("/groovy")
  14. public class GroovyInvokeJavaSpringController {
  15. @Resource
  16. private GroovyClassLoaderRule groovyClassLoaderRule;
  17. @RequestMapping("/groovy-shell/spring")
  18. public String groovyInvokeJavaMethodTest() {
  19. String groovyStr = "package script\n" +
  20. "\n" +
  21. "import com.example.groovy.GroovyInvokeJavaDemo\n" +
  22. "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
  23. "import com.example.groovy.utils.SpringContextUtil\n" +
  24. "\n" +
  25. "/**\n" +
  26. " * @Author: lly\n" +
  27. " * @Date: 2023/7/1\n" +
  28. " */\n" +
  29. "\n" +
  30. "def helloWord() {\n" +
  31. " return \"hello groovy\"\n" +
  32. "}\n" +
  33. "\n" +
  34. "helloWord()\n" +
  35. "\n" +
  36. "def cal(int a, int b) {\n" +
  37. " ShellGroovyDTO dto = new ShellGroovyDTO()\n" +
  38. " dto.setA(a)\n" +
  39. " dto.setB(b)\n" +
  40. " if (b > 0) {\n" +
  41. " dto.setNum(a + b)\n" +
  42. " } else {\n" +
  43. " dto.setNum(a)\n" +
  44. " }\n" +
  45. " return dto\n" +
  46. "};\n" +
  47. "\n" +
  48. "cal(a , b)\n" +
  49. "\n" +
  50. "/** 定义静态变量 **/\n" +
  51. "class Globals {\n" +
  52. " static String PARAM1 = \"静态变量\"\n" +
  53. " static int[] arrayList = [1, 2]\n" +
  54. "}\n" +
  55. "\n" +
  56. "def groovyInvokeJavaMethod(int a, int b) {\n" +
  57. " GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean(\"groovyInvokeJavaDemo\")\n" +
  58. "// return groovyInvokeJavaDemo.groovyInvokeJava();\n" +
  59. " return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b);\n" +
  60. "}\n" +
  61. "\n" +
  62. "groovyInvokeJavaMethod(a, b)";
  63. Binding binding = new Binding();
  64. binding.setVariable("a", 100);
  65. binding.setVariable("b", 100);
  66. GroovyShell groovyShell = new GroovyShell(binding);
  67. Object evaluate = groovyShell.evaluate(groovyStr);
  68. groovyShell.getClassLoader().clearCache();
  69. return (String) evaluate;
  70. }
  71. }

第八步、启动、接口测试

访问“http://localhost:8080/groovy/groovy-shell/spring”即可看到效果。

abfce468a5bc421da81c1c7870d5f85d.png

三、优化

以上我们就将Groovy集成到Java中来了,但是上面的代码有很大的问题,主要体现在两个方面:

第一个方面:通过第五步中我们可以看到,在Groovy中是可以获取到SpringBoot容器对象的,能拿到容器对象就可以获取到容器中所有的东西。这虽然很方便、灵活,但是非常的危险。如果没有做好权限控制,Groovy脚本将会成为攻击你系统最有力的武器!

第二个方面:Groovy脚本用不好,会导致OOM,最终服务器宕机。每次调用这个方法都创建了GroovyShell、Script等实例,随着调用次数的增加,必然会出现OOM。

解决方案是通过GroovyClassLoader的clearCache()函数在调用完毕销毁GroovyShell、Script等实例,但是其实这样仅仅是不够的,导致OOM的原因并不止GroovyShell、Script等实例过多,经过查阅资料得知,如果脚本中的Java代码也创建了对象或者new了实例,即使销毁了GroovyShell也不会销毁脚本中的对象。所以Groovy代码最好是使用缓存管理。

第一步、创建Groovy脚本,使用GroovyClassLoader实现

GroovyClassLoad_1.groovy

  1. package script
  2. import com.example.groovy.GroovyInvokeJavaDemo
  3. import com.example.groovy.groovyshell.ShellGroovyDTO
  4. import com.example.groovy.utils.SpringContextUtil
  5. /**
  6. * @Author: lly
  7. * @Date: 2023/7/1
  8. */
  9. def groovyInvokeJavaMethod(int a, int b) {
  10. GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean("groovyInvokeJavaDemo")
  11. // return groovyInvokeJavaDemo.groovyInvokeJava();
  12. return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b)
  13. }
  14. groovyInvokeJavaMethod(a, b)

GroovyClassLoad_2.groovy

  1. package script
  2. import com.example.groovy.GroovyInvokeJavaDemo
  3. import com.example.groovy.groovyshell.ShellGroovyDTO
  4. import com.example.groovy.utils.SpringContextUtil
  5. /**
  6. * @Author: lly
  7. * @Date: 2023/7/1
  8. */
  9. def groovyInvokeJavaMethod(int a, int b) {
  10. GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean("groovyInvokeJavaDemo")
  11. // return groovyInvokeJavaDemo.groovyInvokeJava();
  12. return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b)
  13. }
  14. groovyInvokeJavaMethod(a, b)

第二步、创建Groovy调用Bean

  1. package com.example.groovy;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.stereotype.Service;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. /**
  7. * @Author: lly
  8. * @Date: 2023/7/2
  9. */
  10. @Service
  11. @Slf4j
  12. public class GroovyInvokeJavaDemo {
  13. public String groovyInvokeJava() {
  14. List<String> lits = new ArrayList<>();
  15. log.info("this is SpringBoot class, groovy script invoke this method ...");
  16. return "this is SpringBoot class, groovy script invoke this method ...";
  17. }
  18. public String groovyInvokeJavaParam(int a, int b) {
  19. List<String> lits = new ArrayList<>();
  20. log.info("this is SpringBoot class, groovy script invoke this method ,param is a:{}, b:{}", a, b);
  21. return "this is SpringBoot class, groovy script invoke this method , a:" + a + ", b:" + b;
  22. }
  23. }

第三步、创建GroovyClassLoader加载类

  1. package com.example.groovy.classloader;
  2. /**
  3. * @Author: lly
  4. * @Date: 2023/7/1
  5. *
  6. * 定义 Groovy 执行的接口
  7. */
  8. public interface GroovyClassLoaderRule {
  9. String run();
  10. }
  11. package com.example.groovy.classloader;
  12. import groovy.lang.Binding;
  13. import groovy.lang.GroovyClassLoader;
  14. import groovy.lang.GroovyObject;
  15. import groovy.lang.Script;
  16. import lombok.extern.slf4j.Slf4j;
  17. import org.apache.groovy.parser.antlr4.util.StringUtils;
  18. import org.codehaus.groovy.runtime.InvokerHelper;
  19. import org.springframework.stereotype.Service;
  20. import javax.annotation.Resource;
  21. import java.util.HashMap;
  22. import java.util.Map;
  23. /**
  24. * @Author: lly
  25. * @Date: 2023/7/1
  26. */
  27. @Slf4j
  28. @Service
  29. public class GroovyClassLoaderRuleImpl implements GroovyClassLoaderRule {
  30. /**
  31. * 脚本容器 :缓存Script,避免创建太多
  32. **/
  33. private static final Map<String, GroovyObject> SCRIPT_MAP = new HashMap<>();
  34. private static final GroovyClassLoader CLASS_LOADER = new GroovyClassLoader();
  35. public static GroovyObject loadScript(String key, String rule) {
  36. if (SCRIPT_MAP.containsKey(key)) {
  37. return SCRIPT_MAP.get(key);
  38. }
  39. GroovyObject groovyObject = loadScript(rule);
  40. SCRIPT_MAP.put(key, groovyObject);
  41. return groovyObject;
  42. }
  43. public static GroovyObject loadScript(String rule) {
  44. if (StringUtils.isEmpty(rule)) {
  45. return null;
  46. }
  47. try {
  48. Class ruleClazz = CLASS_LOADER.parseClass(rule);
  49. if (ruleClazz != null) {
  50. log.info("load rule:" + rule + " success!");
  51. GroovyObject groovyObject = (GroovyObject) ruleClazz.newInstance();
  52. return groovyObject;
  53. }
  54. } catch (Exception e) {
  55. log.error(e.getMessage(), e);
  56. } finally {
  57. CLASS_LOADER.clearCache();
  58. }
  59. log.error("load rule error, can not load Script");
  60. return null;
  61. }
  62. @Override
  63. public String run() {
  64. // 业务逻辑执行,方便配置
  65. String groovyClassLoader1 = "package script\n" +
  66. "\n" +
  67. "import com.example.groovy.GroovyInvokeJavaDemo\n" +
  68. "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
  69. "import com.example.groovy.utils.SpringContextUtil\n" +
  70. "\n" +
  71. "/**\n" +
  72. " * @Author: lly\n" +
  73. " * @Date: 2023/7/1\n" +
  74. " */\n" +
  75. "\n" +
  76. "def groovyInvokeJavaMethod(int a, int b) {\n" +
  77. " GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean(\"groovyInvokeJavaDemo\")\n" +
  78. "// return groovyInvokeJavaDemo.groovyInvokeJava();\n" +
  79. "\n" +
  80. " return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b)\n" +
  81. "}\n" +
  82. "\n" +
  83. "groovyInvokeJavaMethod(a, b)";
  84. String groovyClassLoader2 = "package script\n" +
  85. "\n" +
  86. "import com.example.groovy.GroovyInvokeJavaDemo\n" +
  87. "import com.example.groovy.groovyshell.ShellGroovyDTO\n" +
  88. "import com.example.groovy.utils.SpringContextUtil\n" +
  89. "\n" +
  90. "/**\n" +
  91. " * @Author: lly\n" +
  92. " * @Date: 2023/7/1\n" +
  93. " */\n" +
  94. "\n" +
  95. "def groovyInvokeJavaMethod(int a, int b) {\n" +
  96. " GroovyInvokeJavaDemo groovyInvokeJavaDemo = SpringContextUtil.getBean(\"groovyInvokeJavaDemo\")\n" +
  97. "// return groovyInvokeJavaDemo.groovyInvokeJava();\n" +
  98. "\n" +
  99. " return groovyInvokeJavaDemo.groovyInvokeJavaParam(a, b)\n" +
  100. "}\n" +
  101. "\n" +
  102. "groovyInvokeJavaMethod(a, b)";
  103. Binding binding = new Binding();
  104. binding.setVariable("a", 300);
  105. binding.setVariable("b", 400);
  106. // Script classLoader1 = loadScript("groovyClassLoader1", groovyClassLoader1, binding);
  107. GroovyObject groovyObject = loadScript("groovyClassLoader2", groovyClassLoader2);
  108. Object groovyInvokeJavaMethod = groovyObject.invokeMethod("groovyInvokeJavaMethod", new Object[]{100, 200});
  109. return (String) groovyInvokeJavaMethod;
  110. }
  111. }

第四步、创建请求API

  1. @RequestMapping("/groovy-class-loader/spring")
  2. public String groovyClassLoaderRuleTest() {
  3. String result = groovyClassLoaderRule.run();
  4. return result;
  5. }

第五步、启动验证

287f158562ba497a8ae5f9fb145858a8.png

至此,咱们的Groovy系列就结束啦,代码大家需要的话可以访问我的gitHub网站获取或者留言,我私信发给大家,希望可以帮助到大家。

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

发表评论

表情:
评论列表 (有 0 条评论,175人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Groovy语法讲解

    3.1 变量的类型 在Groovy中,没有基本数据类型,只有对象类型,表面上我们定义基本数据类型,但实际都会帮我们装箱处理: ![5e574f44c5b1fcda00259

    相关 groovy java8_从GroovyJava 8

    Groovy开发人员早已熟知Java 8中新引入的概念和新的语言结构了。在Java新版本即将推出的增强特性中,有很多是Groovy在几年前就已经提供了的。从用于函数式编程风格的

    相关 Groovy

    Groovy 是 用于Java [虚拟机][Link 1]的一种敏捷的 [动态语言][Link 2],它是一种成熟的 [面向对象][Link 3]编程语言,既可以用于面向对象编