最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java 內(nèi)嵌Groovy動(dòng)態(tài)腳本操作

 更新時(shí)間:2021年07月08日 09:24:59   作者:cuichunchi  
這篇文章主要介紹了java 內(nèi)嵌Groovy動(dòng)態(tài)腳本操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

固定的策略有時(shí)候還是無(wú)法滿足千變?nèi)f化的需求變動(dòng),一方面需要支持特定的用戶需求,另一方面又得盡可能的復(fù)用代碼,避免重復(fù)開(kāi)發(fā),這就需要將這部分的特殊的需求剝離出來(lái),采用動(dòng)態(tài)配置規(guī)則的方式來(lái)實(shí)現(xiàn)。

java有三種方式調(diào)用groovy腳本

但是真正在實(shí)際的服務(wù)器環(huán)境中,嵌入groovy腳本往往需要滿足下面的條件:

  1. 可以直接調(diào)用groovy腳本中的方法
  2. 能傳遞對(duì)象到groovy方法中,不僅僅是字符串
  3. 提供腳本緩存機(jī)制,不用每次調(diào)用腳本的時(shí)候,都到磁盤(pán)讀取
  4. 修改groovy后能實(shí)時(shí)生效

第一種:通過(guò)GroovyShell來(lái)執(zhí)行g(shù)roovy腳本

第二種:通過(guò)GroovyClassLoader動(dòng)態(tài)加載Groovy Class

第三種:使用GroovyScriptEngine腳本引擎加載Groovy腳本

本實(shí)例使用第二種動(dòng)態(tài)加載腳本

Groovy的基本語(yǔ)法

由于Groovy腳本語(yǔ)言能夠直接編譯成java的class字節(jié)碼,并且還支持java的類庫(kù),運(yùn)行在java虛擬機(jī)上,其能夠很好的跟java進(jìn)行交互,因此利用groovy的動(dòng)態(tài)特性,來(lái)實(shí)現(xiàn)需求頻繁變動(dòng)的且變態(tài)的需求,并且不需要重啟服務(wù)器。

以下是代碼測(cè)試control類

package com.webTest.dynamicGroovy.controller; 
import groovy.lang.GroovyObject; 
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest; 
import org.apache.log4j.Logger;
import org.codehaus.groovy.control.CompilationFailedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.base.common.GroovyUtils;
import com.webTest.dynamicGroovy.bean.GroovyBean;
import com.webTest.dynamicGroovy.groovyInterface.CallBackGroovyInvoke;
import com.webTest.dynamicGroovy.service.CallBackGroovy;
 
@Controller
@RequestMapping("/groovyTest")
public class GroovyControl {	
	private Logger logger = Logger.getLogger(GroovyControl.class);		
	@Autowired
	private CallBackGroovy callBackGroovy;		
	@ResponseBody
	@RequestMapping(value="/groovy1.do",method={RequestMethod.GET,RequestMethod.POST})
	public  Object testGroovy(HttpServletRequest request) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException{
		logger.info("測(cè)試動(dòng)態(tài)腳本語(yǔ)言Groovy Begin。。。");
		String name="崔春馳";
		String realPath = request.getSession().getServletContext().getRealPath("groovyFile");
		String groovyNameString = "\\hello.groovy";
		String path = realPath+groovyNameString;
		File file = new File(path);
		
		//獲得class,并存放入堆緩存
		Class<?> groovyClass = GroovyUtils.CLASS_LOADER.parseClass("myFirstGroovy",file,true);
		//獲取groovyObject的實(shí)例
		GroovyObject  groovyObject = (GroovyObject) groovyClass.newInstance();
		//反射執(zhí)行方法,得到返回信息   傳多個(gè)參數(shù) new Object[]{bean,request,new HashMap<>()}
		Object invokeResult = groovyObject.invokeMethod("sayHello", name);
		if(invokeResult != null){
			System.out.println(invokeResult.toString());
		}
		//清楚緩存中的map  是為了grrovy腳本變化,清楚堆中緩存,重新類加載
		logger.info("測(cè)試動(dòng)態(tài)腳本語(yǔ)言Groovy End。。。");
		return invokeResult;
	}
	
	@ResponseBody
	@RequestMapping(value="/groovy2.do",method={RequestMethod.GET,RequestMethod.POST})
	public  Object testGroovy2(HttpServletRequest request) throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException{
		logger.info("測(cè)試動(dòng)態(tài)腳本語(yǔ)言Groovy2 Begin。。。");
		String realPath = request.getSession().getServletContext().getRealPath("groovyFile");
		String groovyNameString = "\\testGroovyBean.groovy";
		String path = realPath+groovyNameString;
		File file = new File(path);
		
		GroovyBean bean = new GroovyBean();
		bean.setNameString("王小二");bean.setAge(12);
		Map<String, Object> map = new HashMap<>();
		map.put("address", "江蘇南京");
		
		//獲得class,并存放入堆緩存
		Class<?> groovyClass = GroovyUtils.CLASS_LOADER.parseClass("mySecondGroovy",file,true);
		//獲取groovyObject的實(shí)例
		CallBackGroovyInvoke  groovyObject = (CallBackGroovyInvoke) groovyClass.newInstance();
		//反射執(zhí)行方法,得到返回信息
		Object doCallBackVal = groovyObject.doCallBack(bean, request, map);
		
		if(doCallBackVal instanceof GroovyBean){
			GroovyBean bean2  = (GroovyBean) doCallBackVal;
			System.out.println("用戶信息---》"+bean2.getNameString() + ":"+bean2.getAge()+"歲");
		}
		System.out.println("統(tǒng)一groovy接口返回?cái)?shù)據(jù)————————》"+doCallBackVal);
		//清楚緩存中的map  是為了grrovy腳本變化,清楚堆中緩存,重新類加載
		logger.info("測(cè)試動(dòng)態(tài)腳本語(yǔ)言Groovy2 End。。。");
		return doCallBackVal;
	}
	
	@ResponseBody
	@RequestMapping(value="/clearGroovyCache.do",method={RequestMethod.GET,RequestMethod.POST})
	public void clearCache(){
		//根據(jù)指定key來(lái)清楚
		GroovyUtils.CLASS_LOADER.clearCache("myFirstGroovy");
		//清楚所有
		GroovyUtils.CLASS_LOADER.clearCache();
	}
}

以下為groovyUtils。

public class GroovyUtils { 
 public static GroovyClassLoaderCommon CLASS_LOADER = null; 
 static {
  CompilerConfiguration configuration = CompilerConfiguration.DEFAULT;
  configuration.setSourceEncoding("UTF-8");
  CLASS_LOADER = new GroovyClassLoaderCommon(GroovyControl.class.getClassLoader(), configuration);
 } 
}

以下為GroovyClassLoaderCommon,繼承了GroovyClassLoader,主要是重寫(xiě)了,parseClass方法,并且添加了可以清除sourceCache的map緩存,以及可以remove指定的class信息,用于更改groovy文件后,可以及時(shí)響應(yīng)。

package com.webTest.dynamicGroovy; 
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource; 
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; 
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilerConfiguration; 
public final class GroovyClassLoaderCommon extends GroovyClassLoader{
	
	//這一步可以放入分布式緩存中,如redis中,統(tǒng)一來(lái)管理,防止多次對(duì)groovy的變動(dòng),可以根據(jù)緩存開(kāi)關(guān)來(lái)及時(shí)的更新到j(luò)vm中
	private static final Map<String, Object> CACHEMAP_MAP = new ConcurrentHashMap<>();
	
	public GroovyClassLoaderCommon() {
		super();
	}
	
	public GroovyClassLoaderCommon(ClassLoader loader, CompilerConfiguration config){
		super(loader, config);
	}
	
	/**
	 *
	 * @param file  文件
	 * @param shouldCacheSource   是否緩存
	 * @return
	 * @throws CompilationFailedException
	 * @throws FileNotFoundException
	 * Class<?>
	 * @author 88397658
	 * @since
	 */
	public Class<?> parseClass(String key,File file,
			boolean shouldCacheSource) throws CompilationFailedException, FileNotFoundException {
		GroovyCodeSource codeSource = new GroovyCodeSource(file);
		codeSource.setCachable(shouldCacheSource);
		if(shouldCacheSource) CACHEMAP_MAP.put(key, codeSource.getName());
		return super.parseClass(codeSource);
	}
	
	/**
	 * 清楚緩存
	 */
	public void clearCache(){
		synchronized (this) {
			sourceCache.clear();
		}
	}
	/**
	 * 清楚指定緩存
	 * @param key
	 * void
	 * @author 88397658
	 * @since
	 */
	public void clearCache(String key){
		Object value = CACHEMAP_MAP.get(key);
		synchronized (this) {
			if(sourceCache.containsKey(value)) sourceCache.remove(value);
			if(CACHEMAP_MAP.containsKey(key)) CACHEMAP_MAP.remove(key);
		}
	} 
}
 
import java.util.Date; 
def sayHello(name){
	println name+"向你說(shuō) “你好!!”";
	def date = new Date();
	return "success sayHello()+test  groovy" +date;
} 
<!--可以直接調(diào)用 -->
sayHello('asda');
import com.webTest.dynamicGroovy.groovyInterface.CallBackGroovyInvoke;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import com.webTest.dynamicGroovy.bean.GroovyBean;
import org.slf4j.Logger
import org.slf4j.LoggerFactory
 
class testGroovyBean implements CallBackGroovyInvoke{
	public static final Logger LOGGER = LoggerFactory.getLogger(testGroovyBean.class);	
	def doCallBack(GroovyBean bean ,HttpServletRequest request, Map<String, Object> map){
		LOGGER.info("groovy 中記錄日志。。。。");
		println "測(cè)試接口groovy 獲取用戶信息:"+bean.getNameString() + " ;年齡:"+bean.getAge();
		println "設(shè)置用戶信息:";
		bean.setNameString("蠻王");bean.setAge(200);
		def map1 = ['name':'王大錘','sex':'男'];
		map = map+map1+['weight':'160'];
		def str =  otherMethod();
		LOGGER.info(str);
//		return map
		return bean;
	}
	
	def otherMethod(){
		println "在不重啟應(yīng)用的情況下,調(diào)用內(nèi)部其他方法";
		return "我進(jìn)入了,另一個(gè)方法!";
	}
}

以上就是測(cè)試的這些,至于其框架使用的map容器作為緩存,因jvmGC不會(huì)對(duì)該容器進(jìn)行清除,所以為防止內(nèi)存溢出,可采用自定義的緩存策略,如基于容量、基于時(shí)間、基于java對(duì)象引用、基于緩存算法(LRU最近最少使用、LFU最不常用、FIFO先進(jìn)先出),可不用groovy中的容器,及設(shè)置緩存設(shè)為false,則不放入容器,然后將其生成的實(shí)例可放入分布式緩存中redis即可。

僅為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決spring cloud gateway 獲取body內(nèi)容并修改的問(wèn)題

    解決spring cloud gateway 獲取body內(nèi)容并修改的問(wèn)題

    這篇文章主要介紹了解決spring cloud gateway 獲取body內(nèi)容并修改的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • SpringBoot使用@RestController處理GET和POST請(qǐng)求的代碼詳解

    SpringBoot使用@RestController處理GET和POST請(qǐng)求的代碼詳解

    在Spring?MVC中,@RestController注解的控制器類可以處理多種HTTP請(qǐng)求方法,包括GET和POST,所以本文就給大家詳細(xì)介紹了SpringBoot使用@RestController處理GET和POST請(qǐng)求的示例代碼,需要的朋友可以參考下
    2024-07-07
  • PowerJob的AliOssService工作流程源碼解讀

    PowerJob的AliOssService工作流程源碼解讀

    這篇文章主要介紹了PowerJob的AliOssServiceg工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • SpringBoot如何利用Twilio?Verify發(fā)送驗(yàn)證碼短信

    SpringBoot如何利用Twilio?Verify發(fā)送驗(yàn)證碼短信

    Twilio提供了一個(gè)名為?Twilio?Verify?的服務(wù),專門用于處理驗(yàn)證碼的發(fā)送和驗(yàn)證,下面我們就來(lái)看看如何使用Twilio?Verify實(shí)現(xiàn)發(fā)送驗(yàn)證碼短信吧
    2025-03-03
  • ConditionalOnProperty注解的作用和使用方式

    ConditionalOnProperty注解的作用和使用方式

    在SpringBoot項(xiàng)目開(kāi)發(fā)中,@ConditionalOnProperty注解允許根據(jù)配置文件中的屬性值來(lái)控制配置類是否生效,該注解通過(guò)屬性name和havingValue來(lái)判斷配置是否注入,如果application.properties中的對(duì)應(yīng)屬性值為空或不匹配havingValue設(shè)定值
    2024-09-09
  • java中Ajax與Axios的使用小結(jié)

    java中Ajax與Axios的使用小結(jié)

    在項(xiàng)目中我們經(jīng)常會(huì)遇到需要向請(qǐng)求頭中添加消息的場(chǎng)景,本文主要介紹了java中Ajax與Axios的使用小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • Activiti開(kāi)發(fā)環(huán)境的配置

    Activiti開(kāi)發(fā)環(huán)境的配置

    本篇文章主要內(nèi)容介紹了Activiti開(kāi)發(fā)環(huán)境的配置,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • redis.clients.jedis.exceptions.JedisMovedDataException異常解決

    redis.clients.jedis.exceptions.JedisMovedDataException異常解決

    redis.clients.jedis.exceptions.JedisMovedDataException?異常是在使用?Jedis?客戶端與?Redis?集群進(jìn)行交互時(shí)發(fā)生的,下面就來(lái)介紹一下解決方法,感興趣的可以了解一下
    2024-05-05
  • 詳解Java實(shí)現(xiàn)JSONArray轉(zhuǎn)Map的三種實(shí)現(xiàn)方式

    詳解Java實(shí)現(xiàn)JSONArray轉(zhuǎn)Map的三種實(shí)現(xiàn)方式

    本文主要介紹了Java實(shí)現(xiàn)JSONArray轉(zhuǎn)Map的三種實(shí)現(xiàn)方式,本文只是自己常用的三種,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java的Socket通訊基礎(chǔ)編程完全指南

    Java的Socket通訊基礎(chǔ)編程完全指南

    這篇文章主要介紹了Java的Socket通訊基礎(chǔ)編程,包括對(duì)Socket服務(wù)器的并發(fā)訪問(wèn)方法,是Java網(wǎng)絡(luò)編程中的重要知識(shí),相當(dāng)推薦!需要的朋友可以參考下
    2015-08-08

最新評(píng)論

江永县| 卫辉市| 开封市| 南江县| 井陉县| 拉萨市| 汝城县| 靖宇县| 连山| 平泉县| 商河县| 商城县| 中江县| 藁城市| 古蔺县| 房产| 屯门区| 永仁县| 锡林郭勒盟| 德惠市| 安顺市| 紫云| 罗平县| 高雄县| 乌拉特前旗| 井陉县| 平度市| 马山县| 凤城市| 滨海县| 安岳县| 新晃| 宜春市| 琼中| 五家渠市| 法库县| 新巴尔虎右旗| 曲松县| 两当县| 呼伦贝尔市| 荥阳市|