springBoot使用groovy脚本
语法网址:
https://groovy-lang.cn/integrating.html#_groovy_integration_mechanisms
Apache Groovy是一种强大的、可选的类型和动态语言,具有静态类型和静态编译功能,用于Java平台,旨在通过简洁、熟悉和易于学习的语法提高开发人员的生产力。它可以与任何Java程序顺利集成,并立即为您的应用程序提供强大的功能,包括脚本功能、领域特定语言创作、运行时和编译时元编程以及函数式编程。
Groovy与Java的集成
那么基于如上流程,我们如何结合Groovy和java呢? 基于上面的设计,Groovy脚本的执行本质上只是接受context对象,并且基于context对象中的关键信息进行逻辑判断,输出结果。而结果也保存在context中。 先看看Groovy与java集成的方式:
GroovyClassLoader
用 Groovy 的 GroovyClassLoader ,它会动态地加载一个脚本并执行它。GroovyClassLoader是一个Groovy定制的类装载器,负责解析加载Java类中用到的Groovy类。
GroovyShell
GroovyShell允许在Java类中(甚至Groovy类)求任意Groovy表达式的值。您可使用Binding对象输入参数给表达式,并最终通过GroovyShell返回Groovy表达式的计算结果。
GroovyScriptEngine
GroovyShell多用于推求对立的脚本或表达式,如果换成相互关联的多个脚本,使用GroovyScriptEngine会更好些。GroovyScriptEngine从您指定的位置(文件系统,URL,数据库,等等)加载Groovy脚本,并且随着脚本变化而重新加载它们。如同GroovyShell一样,GroovyScriptEngine也允许您传入参数值,并能返回脚本的值。
SpringBoot集成Groovy
1.添加依赖
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.21</version>
</dependency>
2.配置工具类
@Component
public class GroovyScriptUtils {
@Autowired
private ApplicationContext applicationContext;
@Autowired
@Lazy
private Binding groovyBind;
private GroovyShell groovyShell;
@Bean
public Binding groovyBind() {
Map<String, Object> beanMap = applicationContext.getBeansOfType(Object.class);
return new Binding(beanMap);
}
@PostConstruct
public void init(){
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(this.getClass().getClassLoader());
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
compilerConfiguration.setSourceEncoding("utf-8");
groovyShell = new GroovyShell(groovyClassLoader,groovyBind,compilerConfiguration);
}
public Script readScript(File file) throws FileNotFoundException {
Script parse = null;
try (FileReader fileReader = new FileReader(file)){
parse = groovyShell.parse(fileReader);
} catch (IOException e) {
throw new RuntimeException(e);
}
return parse;
}
}
3.可选加定时任务配置(如果定时执行):
@Configuration
public class SchedulingTaskConfig {
@Bean(name = "myThreadPoolTaskScheduler")
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(60);
taskScheduler.setThreadNamePrefix("task-");
taskScheduler.setAwaitTerminationSeconds(3000);
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
return taskScheduler;
}
}
4.使用示例:
4.1 脚本
import com.study.question.groovy.User;
import com.study.question.groovy.TestService;
import com.study.question.groovy.SpringContextUtil;
import java.util.List;
TestService testService = SpringContextUtil.getBean(TestService.class);
def userList = testService.list;
//方法执行
if(userList == null || userList.size() == 0){
testService.getUser();
userList =testService.list;
}
for (def i = 0; i < userList.size(); i++) {
//根据年龄配置随机数
if(userList.get(i).getAge() < 25){
userList.get(i).setRandom(new Random().nextInt(10));
}else{
userList.get(i).setRandom(new Random().nextInt(20)+new Random().nextInt(10));
}
}
testService.sendDataS(userList);
4.2 执行
@Service
@RequiredArgsConstructor
@Slf4j
public class TestService {
public List<User> list = new ArrayList<>();
private final GroovyScriptUtils groovyScriptUtils ;
private final ThreadPoolTaskScheduler myThreadPoolTaskScheduler;
public void execScript(){
File file = new File("C:\\Users\\a\\Desktop\\study\\test.gv");
try {
Script script = groovyScriptUtils .readScript(file);
myThreadPoolTaskScheduler.scheduleWithFixedDelay(script::run,new Date(),2000);
}catch (Exception e){
log.error("脚本执行失败:{}",e.getMessage());
}
}
public List<User> getUser() {
for (int i = 1; i <= 10; i++) {
User user = new User();
user.setUserId(i);
user.setUserName("用户名-" + i);
user.setAge(20 + i);
user.setAddress("地址-" + i);
list.add(user);
}
return list;
}
public void sendDataS(List<User> objs) {
log.info("数据:{}",objs);
}
}