From 09a2a9af25e6df8c1473d3b88257f37697a8b99b Mon Sep 17 00:00:00 2001 From: Gordian Date: Wed, 30 Jul 2025 18:47:00 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E7=BC=93=E5=AD=98=E4=BB=A5=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/blinkfox/fenix/helper/ParseHelper.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/blinkfox/fenix/helper/ParseHelper.java b/src/main/java/com/blinkfox/fenix/helper/ParseHelper.java index 116305c1..b1692ca6 100644 --- a/src/main/java/com/blinkfox/fenix/helper/ParseHelper.java +++ b/src/main/java/com/blinkfox/fenix/helper/ParseHelper.java @@ -5,7 +5,10 @@ import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.mvel2.MVEL; +import org.mvel2.templates.CompiledTemplate; +import org.mvel2.templates.TemplateCompiler; import org.mvel2.templates.TemplateRuntime; +import java.util.concurrent.ConcurrentHashMap; /** * MVEL 表达式解析相关的工具类. @@ -17,6 +20,9 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ParseHelper { + // 静态缓存,用于存储已编译的模板 + private static final ConcurrentHashMap TEMPLATE_CACHE = new ConcurrentHashMap<>(); + /** * 通过 MVEL 来解析表达式的值,该方法如果解析出错也不抛出异常. * @@ -57,7 +63,8 @@ public static Object parseExpressWithException(String exp, Object context) { */ public static String parseTemplate(String template, Object context) { try { - return (String) TemplateRuntime.eval(template, context); + CompiledTemplate compiledTemplate = TEMPLATE_CACHE.computeIfAbsent(template, TemplateCompiler::compileTemplate); + return (String) TemplateRuntime.execute(compiledTemplate, context); } catch (Exception e) { throw new ParseExpressionException("【Fenix 异常提示】解析模板异常,解析出错的模板为:【" + template + "】.", e); } From acd86f78213593f7fbb6e905b945a52b9597c65b Mon Sep 17 00:00:00 2001 From: Gordian Date: Thu, 31 Jul 2025 14:43:03 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E7=BC=93=E5=AD=98=EF=BC=8C=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=20SoftReference=20=E5=AE=9E=E7=8E=B0=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=95=8F=E6=84=9F=E7=BC=93=E5=AD=98=EF=BC=8C=E9=98=B2=E6=AD=A2?= =?UTF-8?q?=E5=86=85=E5=AD=98=E6=BA=A2=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/blinkfox/fenix/helper/ParseHelper.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/blinkfox/fenix/helper/ParseHelper.java b/src/main/java/com/blinkfox/fenix/helper/ParseHelper.java index b1692ca6..4d963523 100644 --- a/src/main/java/com/blinkfox/fenix/helper/ParseHelper.java +++ b/src/main/java/com/blinkfox/fenix/helper/ParseHelper.java @@ -8,6 +8,8 @@ import org.mvel2.templates.CompiledTemplate; import org.mvel2.templates.TemplateCompiler; import org.mvel2.templates.TemplateRuntime; +import java.util.Map; +import java.lang.ref.SoftReference; import java.util.concurrent.ConcurrentHashMap; /** @@ -20,8 +22,11 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class ParseHelper { - // 静态缓存,用于存储已编译的模板 - private static final ConcurrentHashMap TEMPLATE_CACHE = new ConcurrentHashMap<>(); + /** + * 模板编译缓存,使用 SoftReference 实现内存敏感缓存. + * 当内存不足时,JVM 会回收软引用,防止内存溢出. + */ + private static final Map> TEMPLATE_CACHE = new ConcurrentHashMap<>(); /** * 通过 MVEL 来解析表达式的值,该方法如果解析出错也不抛出异常. @@ -63,7 +68,12 @@ public static Object parseExpressWithException(String exp, Object context) { */ public static String parseTemplate(String template, Object context) { try { - CompiledTemplate compiledTemplate = TEMPLATE_CACHE.computeIfAbsent(template, TemplateCompiler::compileTemplate); + SoftReference ref = TEMPLATE_CACHE.get(template); + CompiledTemplate compiledTemplate = ref != null ? ref.get() : null; + if (compiledTemplate == null) { + compiledTemplate = TemplateCompiler.compileTemplate(template); + TEMPLATE_CACHE.put(template, new SoftReference<>(compiledTemplate)); + } return (String) TemplateRuntime.execute(compiledTemplate, context); } catch (Exception e) { throw new ParseExpressionException("【Fenix 异常提示】解析模板异常,解析出错的模板为:【" + template + "】.", e);