语法网址:
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 {@Autowiredprivate ApplicationContext applicationContext;@Autowired@Lazyprivate Binding groovyBind;private GroovyShell groovyShell;@Beanpublic Binding groovyBind() {Map<String, Object> beanMap = applicationContext.getBeansOfType(Object.class);return new Binding(beanMap);}@PostConstructpublic 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);}}