第十六章、整合groovy

1、整合热身

1.1、适当的整合

  • 并不所有应用都适合整合groovy

1.2、设置依赖

  • 依赖groovy的lib

2、使用GroovyShell解析表达式和脚本

  • 有点类似EL 表达式

2.1、开始简单

  • package com.jack.groovy.ch16
    
    /**
     * @author liangchen* @date 2020/12/6
     */
    @Grab(group='org.apache.httpcomponents', module='httpcore', version='4.2.1')
    def shell = new GroovyShell()
    def result = shell.evaluate("12 + 23")
    assert  result == 35
    
    
    // 显示创建GroovyShell 一些case
    assert  "Hello" == Eval.me("'Hello'")
    // 前面是值,后面是表达式
    assert  1 == Eval.x(1, "x")
    // 两个数据相加
    assert 3 == Eval.xy(1, 2, "x+y")
    // 三个数据相加
    assert 6 == Eval.xyz(1, 2, 3, "x+y+z")
    
    

2.2、通过绑定传参

  • package com.jack.groovy.ch16
    
    /**
     * @author liangchen* @date 2020/12/6
     */
    def binding = new Binding()
    binding.mass = 22.3
    binding.velocity = 10.6
    def shell = new GroovyShell(binding)
    // velocity ** 2  velocity的平方  22.3 * 10.6*10.6 / 2
    def expression = "mass * velocity ** 2/2"
    assert  shell.evaluate(expression) == 1252.814
    binding.setVariable("mass", 25.4)
    assert  shell.evaluate(expression) == 1426.972
    
    // 绑定字段的值
    def bindingFlow = new Binding(x: 6, y: 4)
    def shellFlow = new GroovyShell(bindingFlow)
    shellFlow.evaluate('''
        xSquare = x * x
        yCube = y * y * y
    ''')
    assert  bindingFlow.getVariable("xSquare") == 36
    assert bindingFlow.yCube == 64
    
    // 可以在 表达式完成赋值
    def bindingLocal = new Binding()
    def shellLocal = new GroovyShell(bindingLocal)
    shellLocal.evaluate('''
        def localVariable = 'local variable'
        bindingVariable = 'binding variable'
    ''')
    assert  bindingLocal.getVariable("bindingVariable") == "binding variable"
    

2.3、在运行时生成动态类

  •  package com.jack.groovy.ch16
    
    /**
     * @author liangchen* @date 2020/12/6
     */
    // 利用 evalue 定义动态类
    def shell = new GroovyShell()
    def clazz = shell.evaluate('''
        class MyClass{
            def method(){"value"}
        }
        return MyClass
    ''')
    assert clazz.name == "MyClass"
    def instance = clazz.newInstance()
    assert  instance.method() == "value"
    

2.4、解析脚本

  • package com.jack.groovy.ch16
    
    /**
     * @author liangchen* @date 2020/12/6
     */
    
    // 计算贷款利率
    def monthly = "amount * (rate/12) / (1-(1+rate/12)**-numberOfMonths)"
    def shell = new GroovyShell()
    def script = shell.parse(monthly)
    script.binding.amount = 154000
    script.rate = 3.75/100
    script.numberOfMonths = 240
    
    assert  script.run() == 913.0480050387338
    // 不需要重新解析 monthly 表达式
    script.binding = new Binding(amount: 185000, rate: 3.50 / 100, numberOfMonths: 300)
    assert script.run() == 926.1536089487843
    
    

2.5、运行脚本和类

2.6、GroovyShell更深的参数

  • package com.jack.groovy.ch16
    
    import org.codehaus.groovy.control.CompilerConfiguration
    
    
    /**
     * @author liangchen* @date 2020/12/6
     */
    // 通过配置CompilerConfiguration 类
    // 继承 Script 抽象类,然后定义抽象方法
    abstract class BaseScript extends  Script{
       def multiply(a, b) { a * b}
    }
    
    // 设置compiler配置, evaluate就可以实现这个抽象方法了
    def conf = new CompilerConfiguration()
    conf.setScriptBaseClass("com.jack.groovy.ch16.BaseScript")
    def shell = new GroovyShell(conf)
    def  value = shell.evaluate('''
        multiply(5,6)
    ''')
    assert  value == 30
    

3、使用groovy脚本引擎

3.1、设置引擎

  • // 创建engine
    def engine = new GroovyScriptEngine(".")
    //数组
    def engine = new GroovyScriptEngine([".""../folder"])
    // url格式
    def engine = new GroovyScriptEngine(["file://.", "http://someUrl"]*.toURL() as URL[])
    

3.2、运行脚本

3.3、定义不同资源连接器

4、使用GroovyClassLoader

4.1、解析和加载groovy 类

  • 当前文件夹有个类(Hello.groovy)

  • class Hello {
       def greeting() { "Hello!" }
    
    }
    
    
  • 使用GroovyClassLoader

    • def gc1 = new GroovyClassLoader()
      // 解析这个类
      Class greetingClass = gc1.parseClass(new File("Hello.groovy"))
      assert "Hello!" == greetingClass.newInstance().greeting()
      
      
      // Java 调用方法
      
      GroovyClassLoader gcl = new GroovyClassLoader();
      
      Class greetingClass = gcl.parseClass(new File(" Hello.groovy "));
      
      GroovyObject hello  = (GroovyObject) greetingClass.newInstance();
      
      Object[] args   = {};
      
      assert "Hello!".equals(hello. invokeMethod ("greeting", args));
      

4.2、鸡和蛋依赖问题

  • grooy和java代码同时存在时候的问题

4.3、提供自定义资源加载器

  • 需要继承GroovyResourceLoader,实现loadGroovySource方法

4.4、在安全盒子运行安全

  • grant codeBase "file:${server.home}/classes/~"{
      permission java.security.AllPermission;
    };
     
      grant codeBase "file:/restricted "{
        permission java.util.PropertyPermission "file.encoding", "read"
      }
    

5、spring 整合

5.1、写groovy Bean

5.2、刷新bean

5.3、内嵌脚本

6、Riding Mustang 和JSR-223

6.1、介绍JSR-223

  • Scripting for the java Platform (java脚本平台)

6.2、脚本引擎管理

  • 脚本引擎API是 javax.script.ScriptEngineManager

  • import javax.script.ScriptEngine
    import javax.script.ScriptEngineManager
    
    /**
     * @author liangchen* @date 2020/12/12
     */
    
    ScriptEngineManager scriptEngineManager = new ScriptEngineManager()
    
    ScriptEngine engins = scriptEngineManager.getEngineByName("groovy")
    
    result = engins.eval("3+3")
    println result
    
    
    

6.3、编译和调用脚本引擎

  • package com.jack.groovy.ch16
    
    import javax.script.Compilable
    import javax.script.CompiledScript
    import javax.script.Invocable
    import javax.script.ScriptEngine
    import javax.script.ScriptEngineManager
    
    /**
     * @author liangchen* @date 2020/12/12
     */
    ScriptEngineManager manager = new ScriptEngineManager()
    ScriptEngine scriptEngine = manager.getEngineByName("groovy")
    Compilable compilable = (Compilable) scriptEngine
    //设置一个值
    compilable.put("name", "Dierk")
    
    //设置返回方法, 有点SQL预编译的味道
    CompiledScript script = compilable.compile("return name")
    String dierksName = script.eval()
    println dierksName
    compilable.put("name", "Guillaume")
    String guillaumesName = script.eval()
    println guillaumesName
    
    // Invoke 调用方法
    ScriptEngineManager managerInvoke = new ScriptEngineManager()
    ScriptEngine engine = managerInvoke.getEngineByName("groovy")
    
    Invocable invocable = (Invocable) engine
    // 添加一个方法
    invocable.eval("def upper(s) {s.toUpperCase()}")
    // 调用方法(变成大写)
    Object s = invocable.invokeFunction("upper", "Groovy")
    
    // 添加一个加法的方法
    invocable.eval("def add(a,b){a+b}")
    invocable.invokeFunction("add", new Integer(1), new Integer(2))
    // 调用String 的方法endsWith
    assertTrue(invocable.invokeMethod(s, "endsWith", "Y"))
    
    
    
    
    

6.4、多态编程

  • import javax.script.ScriptEngineManager
    
    /**
     * @author liangchen* @date 2020/12/12
     */
    // 多态编程 ,定义一个斐波那契数列
    def mgr = new ScriptEngineManager()
    assert  mgr.getEngineByName("javascript").eval('''
    
    function factorial(n){
        if(n == 0) {return 1;}
        return n * factorial(n-1);
    }
    factorial(4)
    ''') == 24.0
    

7、精通编译配置

  • 自定义加载配置类

  • import org.codehaus.groovy.control.CompilerConfiguration
    import org.codehaus.groovy.control.customizers.ImportCustomizer
    
    /**
     * @author liangchen* @date 2020/12/12
     */
    
    def conf = new CompilerConfiguration()
    conf.setScriptBaseClass("com.jack.groovy.ch16.BaseScript")
    def shell = new GroovyShell(conf)
    def value = shell.evaluate('''
    multiply(5,6)
    ''')
    assert  value == 30
    
    // 导入自定义类
    
    def config = new CompilerConfiguration()
    def customizer = new ImportCustomizer()
    customizer.addImports('java.util.concurrent.atomic.AtomicInteger',
    'java.util.concurrent.atomic.AtomicLong')
    config.addCompilationCustomizers(customizer)
    def shells = new GroovyShell(config)
    def values = shells.evaluate('''
        def myInt = new AtomicInteger(1)
        def myLong = new AtomicLong(2) 
    ''')
    

7.1、导入自定义

7.2、资源上下文自定义

7.3、写你自己自定义

7.4、配置脚本的编译属性

8、选择整合机制

  1. 简单使用: Eval.me
  2. 单行输入: GroovyShell
  3. 多行,需要重加载: GroovyScriptEngine
  4. 解决依赖和安全问题: GroovyClassLoader
  5. 如果使用Spring: 使用groovy整合Spring
  6. 如果自由发挥: JSR-223规范整合

9、总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值