项目中部署到多个煤矿的上,每一种煤矿的情况都相同,涉及到支架的算法得写好几套,于是想到用脚本实现差异变化多的算法!一开始想到用java调用js脚本去实现,因为这个不需要引入格外的包,js对我来说也没啥学习成本,后来发现js的方法的参数中没办法使用java的对象传参。如果要把java对象分解成多个基本类型的参数传递的话,js的代码实现就变复杂和臃肿了。于是改用groovy脚本去实现,后来经过两个小时的实现,终于调通!groovy的语法和java类似,学习成本很低,且groovy可以引入java的类使用java的对象,调用java的方法也很简单,下面给出实现的代码图文教程。
Groovy是一种基于JVM(Java虚拟机)的动态编程语言,它具有Java的兼容性和许多强大的功能,可以用来快速开发Java应用程序。
以下是Groovy的一些主要特点:
总的来说,Groovy是一种强大、灵活且易于使用的编程语言,无论你是一个Java开发者还是一个想要使用JVM的语言的人,你都可以从Groovy中受益。
首先在springboot项目中引入groovy的依赖,maven引入配置如下:
<dependency>
<groupId>org.codehaus.groovygroupId>
<artifactId>groovy-allartifactId>
<version>2.4.11version>
dependency>
新建一个ScriptProvider脚本使用类,代码如下:
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* @author Lenovo
*/
@Component
@Slf4j
public class ScriptProvider {
private GroovyObject groovyObject;
@Value("${app.work-face}")
private void loadScript(String name){
try (GroovyClassLoader classLoader = new GroovyClassLoader()) {
Class<?> groovyClass = classLoader.parseClass(new File("etc/"+name+".groovy"));
groovyObject= (GroovyObject) groovyClass.newInstance();
} catch (InstantiationException | IOException | IllegalAccessException e) {
log.error(e.getMessage());
}
}
public void overloadScript(String filePath){
try (GroovyClassLoader classLoader = new GroovyClassLoader()) {
Class<?> groovyClass = classLoader.parseClass(new File(filePath));
groovyObject= (GroovyObject) groovyClass.newInstance();
} catch (InstantiationException | IOException | IllegalAccessException e) {
log.error(e.getMessage());
}
}
public double calStentHeight(int i, List<DataValue> dataValues){
Object[] objects = new Object[]{i,dataValues};
Object result=groovyObject.invokeMethod("calStentHeight",objects);
return Double.parseDouble(result.toString());
}
public double revisedStentHeight(int i, List<DataValue> dataValues){
Object[] objects = new Object[]{i,dataValues};
Object result=groovyObject.invokeMethod("revisedStentHeight",objects);
return Double.parseDouble(result.toString());
}
public Object revisedStentStroke(int i, List<DataValue> dataValues) {
Object[] objects = new Object[]{i,dataValues};
Object result=groovyObject.invokeMethod("revisedStentStroke",objects);
return Double.parseDouble(result.toString());
}
}
代码解析
创建一个groovy脚本,以4703.groovy为例,代码如下:
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue
def calStentHeight(int i,List<DataValue> dataValues){
return dataValues.get(i).getValue().getValue();
}
def revisedStentHeight(int i,List<DataValue> dataValues){
double d=dataValues.get(i).getValue().getValue();
int stentNo=i+1;
if(stentNo<=2||stentNo>=92){
if(d>3.6){
d=3.6;
}
if(d<=0){
d=3.3;
}
}else{
if(d>1.9){
d=stentNo==3?1.9:dataValues.get(i-1).getValue().getValue();
}
if(d<=0){
d=1.9;
}
}
return d;
}
def revisedStentStroke(int i,List<DataValue> dataValues){
double d=dataValues.get(i).getValue().getValue();
int stentNo=i+1;
if(stentNo<=2||stentNo>=92){
if(d>900D){
d=900D;
}
if(d<=0D){
d=0D;
}
}else{
if(d>900D||d<=0D){
d=dataValues.get(i-1).getValue().getValue();;
}
}
return d;
}
代码解析:
在springboot中调用groovy脚本中的方法,示例代码如下:
@Resource
private ScriptProvider scriptProvider;
StentsDTO.putStentHeight(key.getPointAddress(),scriptProvider.calStentHeight(i,dataValues));
objValue= scriptProvider.revisedStentHeight(i,dataValues);
代码解析
java无法是实现对具体某个文件操作事件的监听,只能实现文件夹和文件夹下的文件的事件的监听。我们可以通过监听文件夹监听实现对文件的监听。代码如下(代码中只有文件修改事件的监听):
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.file.*;
/**
* @author tarzan
*/
@Component
@AllArgsConstructor
@Slf4j
public class FileSystemWatcher {
private final ScriptProvider scriptProvider;
public void modifyWatch(){
try {
watch(StandardWatchEventKinds.ENTRY_MODIFY);
} catch (IOException | InterruptedException e) {
log.error(e.getMessage());
}
}
private void watch(WatchEvent.Kind<Path> eventKind) throws IOException, InterruptedException {
// 定义你想要监听的路径
Path path = Paths.get("etc");
// 创建 WatchService
WatchService watchService = FileSystems.getDefault().newWatchService();
// 将路径注册到 WatchService,并指定你想要监听的事件类型
path.register(watchService, eventKind);
while (true) {
// 获取下一个文件系统事件
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
// 获取事件类型
WatchEvent.Kind<?> kind = event.kind();
if (kind == StandardWatchEventKinds.OVERFLOW) {
continue;
}
// 获取发生事件的文件
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path fileName = ev.context();
// 打印出发生事件的文件名和事件类型
boolean eventFlag=!fileName.toFile().getName().endsWith("~");
if(eventFlag){
log.info("etc/"+fileName +" be modified");
scriptProvider.overloadScript("etc/"+fileName);
}
}
//睡眠1秒
Thread.sleep(1000);
// 重置 WatchKey,以便接收下一个事件
boolean valid = key.reset();
if (!valid) {
break;
}
}
}
}
代码解析
如果你对文章有疑问或者更好的见解,请在评论区留言!如果文章对你有帮助,请点赞收藏!!!