利用Spring管理热加载的Groovy对象

最近做的项目属于数据分析类型,要求数据分析功能做到快速上线。该项目当前使用的语言是Java + Groovy。 使用Groovy的原因很简单,因为 Groovy 脚本支持热加载功能。项目中,简单的数据分析工作,如一些统计、排序、过滤等,都放在Groovy里完成。需要上线新的数据分析功能时,只需要编写一个新的脚本,并热加载到JVM中即可。

现在希望将一些数据源访问、数据预处理的工作也放到 Groovy 脚本中完成,并具有这样的功能:项目在线上稳定运行期间,可以通过修改数据库中的脚本来完成新产品的上线。

解决方案

  • PlanA: Java + 热加载
  • PlanB: Groovy + 热加载

最终选择的方案是PlanB:让 Groovy 脚本需要具有访问数据源、调用rpc服务等等的能力。核心思路是利用Spring对Groovy脚本进行管理。

  1. Groovy 脚本保存在数据库中。定时任务不断轮训数据库检测Groovy脚本的更新时间,若有更新,则读取脚本内容,并解析为Class。
  2. 然后利用Spring提供的工具类BeanDefinitionBuilder,生成BeanDefinition。BeanDefinition中保存了Groovy脚本的meta信息,比如对其他类的依赖。
  3. 接着,将BeanDefinition放入Spring上下文ApplicationContext中,并调用初始化方法,对bean进行依赖注入。
  4. 最后,调用context.getBean(“xxx”)拿到该脚本。

当然,需要注意的细节有很多,比如服务降级、安全控制等,这里就不展开说了。

架构简图

简单实现

Hello.groovy 这是保存在数据库中的Groovy脚本。

 

复制代码

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

HelloService.java 这是项目中已经提供的服务,现实项目中可以是访问数据源等功能。

 

复制代码

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

第一步,需要拿到Spring上下文 ApplicationContext。这个有很多种实现,比如继承ApplicationContextAware接口等。

第二步,获取到编译后的脚本,如下。

 

复制代码

//从数据库中获取到脚本内容 String scriptContent = "......"; //编译 Class clazz = new GroovyClassLoader().parseClass(scriptContent);

第三步,将bean放入上下文,并进行依赖注入

 

复制代码

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

第四步,从上下文中获取Groovy脚本

 

复制代码

Hello hello = context.getBean("hello"); hello.run(); //console中应当输出下面内容,此时说明HelloService已经成功注入到groovy脚本中了 //now hello


参考资料

  1. Groovy 使 Spring 更出色,第 2 部分 - 在运行时改变应用程序的行为 - 用 Groovy 为 Spring 应用程序添加可动态刷新的 bean
  2. 动态注入 Bean 到 Spring 容器
  3. spring 动态注册 bean 王雁
  4. Spring 动态注册 bean 李佳明

作者:折叠椅
链接:https://juejin.cn/post/6844903640700813325
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值