首頁> Java> java教程> 主體

springboot怎麼整合groovy腳本使用

WBOY
發布: 2023-05-18 23:25:04
轉載
1537 人瀏覽過

在我們的應用中引入腳本能力,可以很好的提升靈活性,我們的核心開發工作可以集中在核心平台能力的開發上,具體場景的功能可以透過腳本來實現,例如jenkins就可以透過groovy腳本來編寫pipeline,可以很靈活的客製化建置流程。 spring本身提供了groovy整合的機制,分為兩種方式,一種是用groovy開發程序,跟用java開發類似,需要經過編譯。一種是將groovy作為腳本來執行,不需要編譯。在此我們介紹的是第二種方式,將groovy作為腳本來使用。

一、概述

在spring中整合groovy腳本,主要有2種思路,一種是在groovy腳本中定義bean,這樣groovy腳本就融入了整個spring的體系,跟使用普通的bean沒有差別。一種是在程式中呼叫groovy腳本,讓groovy腳本成為一個可執行的元件。以下我們分別介紹這2種方式。在spring中聲明groovy腳本中定義的bean有兩種方式,一種是傳統的xml,一種是spring-framework-4中引入的groovy聲明方式。

二、在groovy中定義bean

首先我們定義一個interface:

public interface MyService { String fun(MyDomain myDomain); }
登入後複製

這兒提供了一種思路,我們可以用java程式碼寫預設的interface實現,如果預設實作不符合特定場景的要求時,配合策略模式,用groovy腳本實作特定場景,程式會變的很靈活,配合腳本的熱載入機制,當處理邏輯需要變更時,在程式執行的過程中,我們可以隨時調整腳本內容且能夠及時生效。

在groovy腳本MyServiceImpl.groovy中實作這個interface:

class MyServiceImpl implements MyService { @Autowired FunBean useBean; String myProp; String fun(MyDomain myDomain) { return myDomain.toString() + useBean.getFunName() + myProp; } }
登入後複製

下面分別介紹透過xml和groovy兩種設定方式來宣告bean。

2.1、透過xml設定的方式宣告groovy中實作的bean

透過xml設定宣告bean是spring傳統的方法,這種方法近來已經被透過java程式碼宣告的方式取代,但是對於聲明groovy腳本中定義的bean來說還是最簡單的方法。

    
登入後複製

以上xml程式碼宣告了myServiceXml這個bean,script-source指定了這個bean的來源是classpath:MyServiceImpl.groovy這個腳本檔。將classpath替換為file,可以指定任一位置的腳本檔案。
refresh-check-delay定義了腳本的刷新間隔,當腳本內容改變後,可以自動刷新腳本的內容。
lang:property這個標籤可以對bean的屬性進行初始化賦值。

我們分別用xml和groovy兩種宣告bean的方式來給myProp這個屬性賦值不同的初始值,在後續的示範程式碼中可以看到。

2.2、透過groovy配置的方式聲明groovy中實現的bean

spring-framework-4中引入了groovy聲明bean的方式,我們用groovy來聲明myServiceGroovy這個bean,相比於xml的方式,groovy的聲明方式可讀性更強。

詳細介紹見spring的官方部落格文章: Groovy Bean Configuration in Spring Framework 4

import org.springframework.scripting.groovy.GroovyScriptFactory import org.springframework.scripting.support.ScriptFactoryPostProcessor beans { scriptFactoryPostProcessor(ScriptFactoryPostProcessor) { defaultRefreshCheckDelay = 10000 } myServiceGroovy(GroovyScriptFactory, 'classpath:MyServiceImpl.groovy') { bean -> bean.scope = "prototype" myProp = ' this is Bean Builder init prop' bean.beanDefinition.setAttribute(ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, 6000) } }
登入後複製

透過GroovyScriptFactory可以指定定義bean的groovy腳本位置。透過bean的lambda表達式,可以對bean的屬性進行賦值,除了我們定義的myProp這個屬性外,還可以定義scope和腳本刷新時間。

2.3、呼叫groovy中實作的bean

前面我們透過xml和groovy兩種方式分別宣告了2個bean:myServiceXmlmyServiceGroovy,下面我們在程式中呼叫這2個bean。

@SpringBootApplication @ImportResource({"classpath:xml-bean-config.xml", "classpath:BeanBuilder.groovy"}) public class Application implements CommandLineRunner { @Autowired private MyService myServiceXml; @Autowired private MyService myServiceGroovy; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws ScriptException, ResourceException, IllegalAccessException, InstantiationException { MyDomain myDomain = new MyDomain(); myDomain.setName("test"); System.out.println(myServiceXml.fun(myDomain)); myDomain.setName("test2"); System.out.println(myServiceGroovy.fun(myDomain)); } }
登入後複製

首先我們透過@ImportResource來引入bean的聲明文件,然後就是普通的bean的依賴注入和方法調用,可以看到在bean的使用上,腳本定義的bean和用程式寫的bean沒有任何差別。在run方法中,我們分別呼叫了myServiceXml和myServiceGroovy的這2個bean的fun方法。執行run方法可以看到輸出到結果:

MyDomain(name=test)FunBean this is xml init prop MyDomain(name=test2)FunBean this is Bean Builder init prop
登入後複製

三、執行groovy腳本

#除了前面提到的在groovy中實作bean以外,我們還可以透過groovy提供的GroovyScriptEngine來執行groovy腳本,這種方式不依賴springframework,在普通的java程式中也可以使用。

@Component public class MyEngine { private final GroovyScriptEngine engine; @Autowired private FunBean funBean; public MyEngine() throws IOException { engine = new GroovyScriptEngine(ResourceUtils.getFile("classpath:scripts/").getAbsolutePath() , this.getClass().getClassLoader()); } public void runScript(int x, int y) throws IllegalAccessException, InstantiationException, ResourceException, ScriptException { Class calcClass = engine.loadScriptByName("CalcScript.groovy"); GroovyObject calc = calcClass.newInstance(); Object result = calc.invokeMethod("calcSum", new Object[]{x, y}); System.out.println("Result of CalcScript.calcSum() method is " + result); Binding binding = new Binding(); binding.setVariable("arg", "test"); binding.setVariable("funBean", funBean); Object result1 = engine.run("CalcScript.groovy", binding); System.out.println("Result of CalcScript.groovy is " + result1); } }
登入後複製

首先我們初始化GroovyScriptEngine,在建構方法中傳入腳本檔案的路徑。

執行腳本的方法有2種,一種是取得到GroovyObject,透過invokeMethod來執行腳本中的某個方法,方法的參數透過Object陣列傳入。

Class calcClass = engine.loadScriptByName("CalcScript.groovy"); GroovyObject calc = calcClass.newInstance(); Object result = calc.invokeMethod("calcSum", new Object[]{x, y});
登入後複製

第二種是直接執行groovy腳本,可以透過Binding將變數傳遞到groovy腳本。

Binding binding = new Binding(); binding.setVariable("arg", "test"); binding.setVariable("funBean", funBean); Object result1 = engine.run("CalcScript.groovy", binding);
登入後複製

以上是springboot怎麼整合groovy腳本使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!