Script Plugin
对应模块:
io.gitee.lcgyl:lcgyl-script-plugin
动态脚本引擎集成,支持在 Java 应用中安全地运行 Groovy, Aviator 等动态脚本。
✨ 特性
- ✅ 多引擎适配 - 统一抽象接口,支持 Groovy, Aviator, QLExpress
- ✅ 高性能缓存 - 脚本编译结果自动缓存,避免重复编译
- ✅ 沙箱安全 - 可限制脚本权限,防止恶意代码执行
- ✅ 灵活绑定 - 支持将 Spring Bean 或 Java 对象绑定到脚本上下文
🚀 快速开始
依赖引入
1. 引入核心模块
gradle
implementation 'io.gitee.lcgyl:lcgyl-script-plugin:2.2.0'2. 选择脚本引擎(按需引入)
gradle
// Groovy 引擎支持
implementation 'io.gitee.lcgyl:lcgyl-script-groovy-plugin:2.2.0'
// Aviator 引擎支持
implementation 'io.gitee.lcgyl:lcgyl-script-aviator-plugin:2.2.0'配置
yaml
lcgyl:
script:
default-engine: groovy # groovy, aviator
cache:
enabled: true
max-size: 1000
sandbox:
enabled: true
allowed-classes:
- java.lang.*
- java.util.*基础使用
java
@Service
public class ScriptService {
@Inject
private ScriptEngine scriptEngine;
// 执行简单表达式
public Object evaluate(String expression, Map<String, Object> context) {
return scriptEngine.execute(expression, context);
}
// 计算价格(Aviator 表达式)
public BigDecimal calculatePrice(BigDecimal basePrice, int quantity, double discount) {
String expression = "basePrice * quantity * (1 - discount)";
Map<String, Object> context = Map.of(
"basePrice", basePrice,
"quantity", quantity,
"discount", discount
);
return (BigDecimal) scriptEngine.execute(expression, context);
}
}Groovy 脚本
java
@Service
public class GroovyScriptService {
@Inject
@Named("groovy")
private ScriptEngine groovyEngine;
// 执行 Groovy 脚本
public Object runGroovy(String script, Map<String, Object> bindings) {
return groovyEngine.execute(script, bindings);
}
// 动态规则校验
public boolean validateOrder(Order order) {
String script = """
// 校验订单金额
if (order.totalAmount > 10000) {
return order.userId != null && order.addressId != null
}
return true
""";
return (boolean) groovyEngine.execute(script, Map.of("order", order));
}
// 动态计算运费
public BigDecimal calculateShipping(Order order) {
String script = """
def weight = order.items.sum { it.weight * it.quantity }
def basePrice = 10
if (weight <= 1) return basePrice
if (weight <= 5) return basePrice + (weight - 1) * 3
return basePrice + 12 + (weight - 5) * 2
""";
return (BigDecimal) groovyEngine.execute(script, Map.of("order", order));
}
}规则引擎场景
java
@Service
public class RuleEngineService {
@Inject
private ScriptEngine scriptEngine;
@Inject
private RuleRepository ruleRepository;
// 从数据库加载规则并执行
public Object executeRule(String ruleCode, Map<String, Object> facts) {
Rule rule = ruleRepository.findByCode(ruleCode);
return scriptEngine.execute(rule.getScript(), facts);
}
// 促销规则计算
public PromotionResult applyPromotion(Order order, String promotionCode) {
Promotion promotion = promotionRepository.findByCode(promotionCode);
Map<String, Object> context = Map.of(
"order", order,
"user", userService.getUser(order.getUserId()),
"helper", new PromotionHelper() // 辅助工具类
);
return (PromotionResult) scriptEngine.execute(promotion.getScript(), context);
}
}沙箱安全
java
@Service
public class SafeScriptService {
@Inject
private ScriptEngineFactory engineFactory;
public Object executeSandboxed(String script, Map<String, Object> context) {
// 创建受限的脚本引擎
ScriptEngine sandboxEngine = engineFactory.create(ScriptConfig.builder()
.sandbox(true)
.maxExecutionTime(Duration.ofSeconds(5))
.maxMemory(10 * 1024 * 1024) // 10MB
.allowedClasses(List.of(
"java.lang.String",
"java.lang.Math",
"java.util.List",
"java.util.Map"
))
.build());
return sandboxEngine.execute(script, context);
}
}