SpringBoot整合Groovy腳本實(shí)現(xiàn)動(dòng)態(tài)編程詳解
Groovy簡(jiǎn)介
Groovy 是增強(qiáng) Java 平臺(tái)的唯一的腳本語(yǔ)言。它提供了類似于 Java 的語(yǔ)法,內(nèi)置映射(Map)、列表(List)、方法、類、閉包(closure)以及生成器。腳本語(yǔ)言不會(huì)替代系統(tǒng)編程語(yǔ)言,兩者是相互補(bǔ)充的。
大名鼎鼎的 Gradle,背后是 Groovy。Spring 的未來(lái)越來(lái)越多的使用 Groovy,甚至在用 Jira 跟蹤項(xiàng)目時(shí),背后也有 Groovy。實(shí)際上,就應(yīng)用場(chǎng)景而言,Java 開(kāi)發(fā)已經(jīng)有越來(lái)越多的 Groovy 出現(xiàn)在后臺(tái)了。而對(duì)于一般的應(yīng)用開(kāi)發(fā),只要能用 Java 就都能用到 Groovy,唯一的難點(diǎn)只在于能不能招到足夠的人員。
應(yīng)用場(chǎng)景
- 連接已有的組件
- 處理經(jīng)常變化的多種類型的實(shí)體
- 具有圖形化用戶界面
- 擁有快速變化的功能
Groovy腳本的基礎(chǔ)概念請(qǐng)移步
集成與使用
那么接下來(lái)介紹SpringBoot如何集成Groovy腳本,并應(yīng)用到實(shí)際開(kāi)發(fā)中。
第一步、與SpringBoot集成
1、pom.xml文件如下:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
第二步、寫(xiě)出Groovy版本的“Hello World”
1、HelloWorld.groovy腳本代碼
package groovy
def HelloWorld(){
println "hello world"
}
2、創(chuàng)建測(cè)試類GroovyTest.java
package com.example.springbootgroovy.service;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
/**
* 這個(gè)是Groovy的第一個(gè)小程序,腳本為:
*
package groovy
def helloworld(){
println "hello world"
}
*
*/
public class GroovyTest {
public static void main(String[] args) throws Exception {
//創(chuàng)建GroovyShell
GroovyShell groovyShell = new GroovyShell();
//裝載解析腳本代碼
Script script = groovyShell.parse("package groovy\n" +
"\n" +
"def HelloWorld(){\n" +
" println \"hello world\"\n" +
"}");
//執(zhí)行
script.invokeMethod("HelloWorld", null);
}
}
3、運(yùn)行結(jié)果

第三步、傳入變量與獲取返回值
1、變量與返回值Groovy腳本代碼
package groovy
/**
* 簡(jiǎn)易加法
* @param a 數(shù)字a
* @param b 數(shù)字b
* @return 和
*/
def add(int a, int b) {
return a + b
}
/**
* map轉(zhuǎn)化為String
* @param paramMap 參數(shù)map
* @return 字符串
*/
def mapToString(Map<String, String> paramMap) {
StringBuilder stringBuilder = new StringBuilder();
paramMap.forEach({ key, value ->
stringBuilder.append("key:" + key + ";value:" + value)
})
return stringBuilder.toString()
}
2、創(chuàng)建測(cè)試類GroovyTest2.java
package com.example.springbootgroovy.service;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import java.util.HashMap;
import java.util.Map;
/**
* 向Groovy腳本中傳入變量,以及獲取返回值
*/
public class GroovyTest2 {
public static void main(String[] args) {
//創(chuàng)建GroovyShell
GroovyShell groovyShell = new GroovyShell();
//裝載解析腳本代碼
Script script = groovyShell.parse("package groovy\n" +
"\n" +
"/**\n" +
" * 簡(jiǎn)易加法\n" +
" * @param a 數(shù)字a\n" +
" * @param b 數(shù)字b\n" +
" * @return 和\n" +
" */\n" +
"def add(int a, int b) {\n" +
" return a + b\n" +
"}\n" +
"\n" +
"/**\n" +
" * map轉(zhuǎn)化為String\n" +
" * @param paramMap 參數(shù)map\n" +
" * @return 字符串\n" +
" */\n" +
"def mapToString(Map<String, String> paramMap) {\n" +
" StringBuilder stringBuilder = new StringBuilder();\n" +
" paramMap.forEach({ key, value ->\n" +
" stringBuilder.append(\"key:\" + key + \";value:\" + value)\n" +
" })\n" +
" return stringBuilder.toString()\n" +
"}");
//執(zhí)行加法腳本
Object[] params1 = new Object[]{1, 2};
int sum = (int) script.invokeMethod("add", params1);
System.out.println("a加b的和為:" + sum);
//執(zhí)行解析腳本
Map<String, String> paramMap = new HashMap<>();
paramMap.put("科目1", "語(yǔ)文");
paramMap.put("科目2", "數(shù)學(xué)");
Object[] params2 = new Object[]{paramMap};
String result = (String) script.invokeMethod("mapToString", params2);
System.out.println("mapToString:" + result);
}
}
3、運(yùn)行結(jié)果

第四步、啟動(dòng)SpringBoot
在Groovy腳本中通過(guò)SpringContextUtil獲取SpringBoot容器中的Bean
1、創(chuàng)建SpringContextUtil.java
package com.example.springbootgroovy.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Spring上下文獲取
*/
@Component
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;
}
/**
* 通過(guò)name獲取 Bean.
*
* @param name
* @return
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* 通過(guò)class獲取Bean.
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
/**
* 通過(guò)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);
}
}
2、創(chuàng)建GroovyTestService.java,并加上@Service注解加入到SpringBoot容器中
package com.example.springbootgroovy.service;
import org.springframework.stereotype.Service;
@Service
public class GroovyTestService {
public void test(){
System.out.println("我是SpringBoot框架的成員類,但該方法由Groovy腳本調(diào)用");
}
}
3、Groovy腳本如下
package groovy
import com.example.springbootgroovy.service.GroovyTestService
import com.example.springbootgroovy.util.SpringContextUtil
/**
* 靜態(tài)變量
*/
class Globals {
static String PARAM1 = "靜態(tài)變量"
static int[] arrayList = [1, 2]
}
def getBean() {
GroovyTestService groovyTestService = SpringContextUtil.getBean(GroovyTestService.class);
groovyTestService.test()
}
4、啟動(dòng)類代碼如下
package com.example.springbootgroovy;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/groovy")
@SpringBootApplication
public class SpringBootGroovyApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootGroovyApplication.class, args);
}
@RequestMapping("/test")
public String test() {
//創(chuàng)建GroovyShell
GroovyShell groovyShell = new GroovyShell();
//裝載解析腳本代碼
Script script = groovyShell.parse("package groovy\n" +
"\n" +
"import com.example.springbootgroovy.service.GroovyTestService\n" +
"import com.example.springbootgroovy.util.SpringContextUtil\n" +
"\n" +
"/**\n" +
" * 靜態(tài)變量\n" +
" */\n" +
"class Globals {\n" +
" static String PARAM1 = \"靜態(tài)變量\"\n" +
" static int[] arrayList = [1, 2]\n" +
"}\n" +
"\n" +
"def getBean() {\n" +
" GroovyTestService groovyTestService = SpringContextUtil.getBean(GroovyTestService.class);\n" +
" groovyTestService.test()\n" +
"}");
//執(zhí)行
script.invokeMethod("getBean", null);
return "ok";
}
}
5、啟動(dòng)后調(diào)用接口:http://localhost:8080/groovy/test
運(yùn)行結(jié)果如下

注意!??!
通過(guò)第四步中我們可以看到,在Groovy中是可以獲取到SpringBoot容器對(duì)象的。雖然很方便,但是很危險(xiǎn)。如果沒(méi)有做好權(quán)限控制,Groovy腳本將會(huì)成為攻擊你系統(tǒng)最有力的武器?。。?/p>
以上就是SpringBoot整合Groovy腳本實(shí)現(xiàn)動(dòng)態(tài)編程詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot整合Groovy動(dòng)態(tài)編程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用.NET Core3.0創(chuàng)建一個(gè)Windows服務(wù)的方法
這篇文章主要介紹了使用.NET Core3.0創(chuàng)建一個(gè)Windows服務(wù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-04
java ThreadPoolExecutor線程池拒絕策略避坑
這篇文章主要為大家介紹了java ThreadPoolExecutor拒絕策略避坑踩坑示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
使用jenkins+maven+git發(fā)布jar包過(guò)程詳解
這篇文章主要介紹了使用jenkins+maven+git發(fā)布jar包過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Spring boot集成Go-FastDFS實(shí)現(xiàn)圖片上傳刪除等功能實(shí)現(xiàn)
這篇文章主要介紹了Spring boot集成Go-FastDFS實(shí)現(xiàn)圖片上傳刪除等功能實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Java使用Collections.sort()排序的示例詳解
這篇文章主要介紹了Java使用Collections.sort()排序的示例詳解,Collections.sort(list, new PriceComparator());的第二個(gè)參數(shù)返回一個(gè)int型的值,就相當(dāng)于一個(gè)標(biāo)志,告訴sort方法按什么順序來(lái)對(duì)list進(jìn)行排序。對(duì)此感興趣的可以了解一下2020-07-07
Spring Boot之AOP配自定義注解的最佳實(shí)踐過(guò)程
這篇文章主要給大家介紹了關(guān)于Spring Boot之AOP配自定義注解的最佳實(shí)踐過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11

