pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Java接口:
public interface Run {
public void speed(int s);
}
Groovy实现类:
class TomRun implements Run{
@Override
void speed(int s) {
println 'I m tom running '+s
}
}
Java客户端加载groovy文件调用:
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import java.io.File;
public class ClientRun {
public static void main(String[] args) {
try {
GroovyClassLoader loader= new GroovyClassLoader();
//把groovy放在E盘或是随便一个目录下
Class groovyClass =loader.parseClass(new File("E:\\TomRun.groovy"));
GroovyObject object =(GroovyObject) groovyClass.newInstance();
Run r = (Run)object;
r.speed(1000);
//定期清除ThreadGroupContext中的缓存后,实现了对Groovy加载类的垃圾回收,避免出现OOM的问题
Introspector.flushCaches();
loader.clearCache();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果
正常调用,无需编译,运行时加载groovy文件
还可以把脚本写在数据库中,读取数据库执行文件
package org.example;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import org.example.data.Code;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import java.beans.Introspector;
import java.io.File;
import java.util.List;
@Component
public class ClientRun {
@Autowired
MongoTemplate mongoTemplate;
public void exec() {
try {
Query query = new Query(Criteria.where("status").is(0));
query.with(Sort.by(
Sort.Order.asc("order")));
List<Code> list = mongoTemplate.find(query, Code.class);
GroovyClassLoader loader= new GroovyClassLoader();
// Class groovyClass =loader.parseClass(new File("E:\\project\\mock\\src\\main\\java\\org\\example\\groovy\\GroovyRun.groovy"));
for (Code c:list
) {
// Class groovyClass =loader.parseClass(new File("E:\\TomRun.groovy"));
Class groovyClass =loader.parseClass(c.getScript());
GroovyObject object =(GroovyObject) groovyClass.newInstance();
Run r = (Run)object;
r.speed(1000);
}
Introspector.flushCaches();
loader.clearCache();
} catch (Exception e) {
e.printStackTrace();
}
}
}
mongoDB实体类
package org.example.data;
import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
@Document(collection="code")
public class Code implements Serializable {
private String script;
private int status;
private int order;
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}
mongoDB插入一条脚本记录
{
"order" : 1.0,
"status" : 0.0,
"script" : "import org.example.Run\n\n\nclass GroovyRun implements Run{\n\n @Override\n void speed(int s) {\n println 'I m tom running '+s\n }\n\n\n}",
}
执行Test方法
再加一条记录,按照order指定的顺序执行TestRun脚本顺序为1,GroovyRun脚本顺序为2
{
"_id" : ObjectId("64812acfc7a9301110c95ef3"),
"order" : 2.0,
"status" : 0.0,
"script" : "import org.example.Run\n\n\nclass GroovyRun implements Run{\n\n @Override\n void speed(int s) {\n println 'I m tom running '+s\n }\n\n\n}"
}
{
"_id" : ObjectId("648130e0c7a9301110c95ef6"),
"order" : 1.0,
"status" : 0.0,
"script" : "import org.example.Run\n\n\nclass TestRun implements Run{\n\n @Override\n void speed(int s) {\n println 'I m test running '+s\n }\n\n\n}"
}
执行Test方法
完成
源码demo: