結合Spring和Groovy解決腳本熱加載

前言

去年寫過一篇文件介紹了採用jpython解決動態配置熱加載的問題jpython解決熱加載,今年在實現規則引擎過程當中準備進行升級,採用groovy腳本解決。java

方案

將一些規則相關,如統計,排序,過濾,放在groovy腳本中,在須要時將腳本熱加載到jvm中進行邏輯使用。python

同時能夠經過動態引入腳本方式,實現功能在線更迭。spring

  • Groovy+熱加載

Groovy腳本具備訪問RPC能力,調用RPC服務,引入Spring對Groovy腳本進行管理。數據庫

  1. 定時獲取Groovy腳本,讀取元信息,解析爲Class。
  2. 利用Spring工具類BeanDefinitionBuilder生成BeanDefinition,完成對其餘類進行依賴。
  3. 將BeanDefinition放入Spring上下文ApplicationContext中,並調用初始化方法,對bean進行依賴注入。
  4. 調用context.getBean("x")拿到腳本。

實現

Groovy腳本app

import org.springframework.beans.factory.annotation.Autowired;
class Hello
 {
    @Autowired
    HelloService service;
	
    HelloService getService() {
        return service
    }
    def run() {
        print(service.hello())
    }
}

已有的HelloService.javajvm

import org.springframework.stereotype.Component;
@Component
public class HelloService
 {
    public String hello() {
        return "now hello";
    }
}

須要拿到Spring上下文ApplicationContext,能夠繼承ApplicationContextAware接口。工具

獲取編譯腳本:ui

//從數據庫中獲取到腳本內容
String scriptContent = "......";
//編譯
Class clazz = new GroovyClassLoader().parseClass(scriptContent);

將bean放入上下文,並進行依賴注入:code

BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
context.getAutowireCapableBeanFactory().applyBeanPostProcessorsAfterInitialization(beanDefinition, "hello");
beanFactory.registerBeanDefinition("hello", beanDefinition);

以後從上下文中獲取Groovy腳本:blog

Hello hello = context.getBean("hello");
hello.run();
//console中應當輸出下面內容,此時說明HelloService已經成功注入到groovy腳本中了
//now hello
相關文章
相關標籤/搜索