Java中使用Groovy

Groovy 是什么?

Apache的Groovy是Java平台上设计的面向对象编程语言。Groovy是一门基于JVM的脚本语言,这门动态语言拥有类似Python、Ruby和Smalltalk中的一些特性,可以作为Java平台的脚本语言使用,Groovy代码动态地编译成运行于Java虚拟机(JVM)上的Java字节码,并与其他Java代码和库进行互操作。

Java 为何需要 Groovy ?

Groovy 特性如下:

语法上支持动态类型,闭包等新一代语言特性
无缝集成所有已经存在的Java类库
既支持面向对象编程也支持面向过程编程
执行方式可以将groovy编写的源文件编译成class字节码文件,然后交给JVM去执行,也可以直接将groovy源文件解释执行。
Groovy可以与Java完美结合,而且可以使用java所有的库

举例说明:
业务场景中
不同的流程模板生成的事项在完结时可以做不同的逻辑处理,因为流程模板有很多,且这些逻辑都是很定制化的内容,如果维护在java代码中则很冗余且开发成本高,可无法对用户开放,这时使用groovry的话,在java代码中开发一个入口,事项完结时执行,这个入口可以去调用groovry代码(可以维护在配置文件中,可以维护在数据库中),以实现逻辑定制处理;

具体使用:



import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.codehaus.groovy.control.CompilerConfiguration;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class GroovyUtils {

    private static CompilerConfiguration compilerConfiguration = new CompilerConfiguration();

    static {
        compilerConfiguration.setScriptBaseClass(GroovyCustom.class.getName());
    }

    public static GroovyShell bindShell(Map map){
        return new GroovyShell(new Binding(map), compilerConfiguration);
    }

    public static void removeBindingByKeys(GroovyShell groovyShell, String... keys){
        Map resource = groovyShell.getContext().getVariables();
        for (String key: keys) {
            resource.remove(key);
        }
    }

// 此静态类InitCroovy 中维护一个map和字符串script属性
//map是new Binding(map)时使用的,放到map中的值,在groovry脚本中可以使用
//script是groovyShell.evaluate(initCroovy.getScript() + actionScript)时使用的,因为grovvry代码中也需要使用一些工具类或者其他的类的引入,这里可以将一些常用的公共的引入放到script中维护,比如utilParam中维护了常用的工具类
    public static class InitCroovy {

        private Map<String, Object> map;
        private StringBuffer script;


        private InitCroovy() {
            initParam();
        }

        private InitCroovy(Map map) {
            this.map = map;
            initParam();
        }


        public static InitCroovy of(Map map) {
            return new InitCroovy(map);
        }

        private void initParam(){
            if (MapUtils.isEmpty(map)) {
                map = new HashMap<>();
            }
            if (script == null) {
                script = new StringBuffer();
            }
        }




        public InitCroovy utilParam() {
            script.append("import org.apache.commons.lang3.StringUtils;");
            script.append("import java.util.Collections;");
            script.append("import java.util.Arrays;");
            script.append("import org.apache.commons.collections.CollectionUtils;");
            script.append("import org.apache.commons.collections.MapUtils;");
            script.append("import com.alibaba.aecp.app.common.util.EmployeeUtils;");
            script.append("import com.alibaba.aecp.app.common.util.CommonUtils;");
            script.append("import com.alibaba.aecp.app.common.util.PatternUtil;");
            script.append("import com.alibaba.aecp.app.common.util.StripHtmlUtils;");
            script.append("import com.alibaba.fastjson.TypeReference;");
            return this;
        }

      
        public InitCroovy customParam(Map<String, Object> map, String script) {
            if (MapUtils.isNotEmpty(map)) {
                this.map.putAll(map);
            }
            if (StringUtils.isNotBlank(script)) {
                this.script.append(script);
            }
            return this;
        }

        public void setVariable(String name, Object value) {
            map.put(name, value);
        }

        public void removeVariableByKeys(String... keys) {
            Arrays.stream(keys).forEach(key -> map.remove(key));
        }

        public Map<String, Object> getParam() {
            return map;
        }

        public String getScript() {
            return script.toString();
        }
    }
}

public class GroovyCustom extends Script {

	@Override
	public Object run() {
		return GroovyCustom.class.getDeclaredMethods();
	}

	//获取 Object 类型 对象集合中 某一元素 的 集合
	public static Object arrayValue(Object array, String key, String type) {
		List<Object> keyList = new ArrayList<>();

		try {
			if (!(array instanceof List) || CollectionUtils.isEmpty((List) array)) {
				return null;
			}
			keyList = ((List<Map>) (JsonUtils.shift((List) array, Map.class))).stream().map(map -> map.get(key)).collect(Collectors.toList());
		} catch (Exception e) {
			log.error("arrayValue :", e);
		}

		return CommonUtils.resultType(keyList, type);
	}


}

调用代码

1. 构建InitCroovy中的map属性,map是new Binding(map)时使用的,放到map中的值,在groovry脚本中可以使用
GroovyUtils.InitCroovy initCroovy = GroovyUtils.InitCroovy.of(new HashMap()) .utilParam();
2.使用GroovyShell对象 执行脚本
Binding binding=new Binding(map);
GroovyShell groovyShell=GroovyUtils.bindShell(binding);
groovyShell.evaluate(/具体的groovry脚本/)
也可以写成:Object value = GroovyUtils.bindShell(initGroovy.getParam()).evaluate(initGroovy.getScript());
3.compilerConfiguration.setScriptBaseClass(GroovyCustom.class.getName());

CompilerConfiguration提供内置的支持能力与自定义脚本能力;在GroovyCustom中自定义一些方法,在evaluate方法中可以直接使用

  public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> mapList = new ArrayList<>();
        mapList.add(new HashMap<String, Object>() {{ put("name", "name1"); }} );
        mapList.add(new HashMap<String, Object>() {{ put("name", "name2"); }} );


        map.put("aaa", new HashMap<String, Object>() {{ put("bbb", mapList); }});

        Object value = GroovyUtils.bindShell(map).evaluate("arrayValue(aaa.bbb, /name/, /String/)");

        System.out.println(value);
    }

4.groovry脚本的定义

//代码中需要用的类型都要引入
        import com.alibaba.aecp.app.common.constants.HadleyConstants;
       
        //groovry脚本中无法打印日志,可以拼接字符串返回字符串,在调用执行groovyShell.evaluate的地方获取返回值然后打印
        StringBuffer logger = new StringBuffer();
   
        //if判断也需要;结尾
        if (CollectionUtils.isEmpty(businessOwnershipList)) {
        	  //groovry的字符串需要用/abcdefg/双斜杠标识
            logger.append(/abcdefg\r\n/);
            return logger;
        };

         //lambada表达式的写法和java不太一样,每个Function、Predicate函数式接口的参数都需要加上{}和 as Function<? super 处理的数据类型, ? super 返回的数据类型>
        Map<String, People> eventsExtraDataDOMap = peopleList.stream().collect(
                Collectors.toMap({ k -> k.getName() } as Function<? super People, ? super String>,
                        { v -> v } as Function<? super People, ? super People>)
        );
       
    
        List<peopleExt> businessTypeObligationList = peopleList.stream().map(
                { people ->
                    PeopleExt peopleExt = new PeopleExt();
                    return peopleExt;
                } as Function<? super People, ? extends PeopleExt>)
                .collect(
                        Collectors.toList());
    
        return logger;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值