11package org .hswebframework .web .crud .events .expr ;
22
3- import io .netty .util .concurrent .FastThreadLocal ;
43import jakarta .annotation .Nonnull ;
54import lombok .extern .slf4j .Slf4j ;
65import org .hswebframework .ezorm .rdb .mapping .EntityColumnMapping ;
76import org .hswebframework .web .crud .query .QueryHelperUtils ;
7+ import org .hswebframework .web .recycler .Recycler ;
88import org .springframework .context .expression .MapAccessor ;
99import org .springframework .core .convert .TypeDescriptor ;
1010import org .springframework .expression .*;
2020@ Slf4j
2121public class SpelSqlExpressionInvoker extends AbstractSqlExpressionInvoker {
2222
23+ static ExtMapAccessor accessor = new ExtMapAccessor ();
24+
2325 protected static class SqlFunctions extends HashMap <String , Object > {
2426
2527 private final EntityColumnMapping mapping ;
@@ -37,9 +39,9 @@ public Object get(Object key) {
3739 }
3840 if (val == null ) {
3941 val = mapping
40- .getPropertyByColumnName (String .valueOf (key ))
41- .map (super ::get )
42- .orElse (null );
42+ .getPropertyByColumnName (String .valueOf (key ))
43+ .map (super ::get )
44+ .orElse (null );
4345 }
4446 return val ;
4547 }
@@ -82,37 +84,35 @@ public Object coalesce(Object... args) {
8284 }
8385 }
8486
85- static final FastThreadLocal <StandardEvaluationContext > SHARED_CONTEXT = new FastThreadLocal <StandardEvaluationContext >() {
86- @ Override
87- protected StandardEvaluationContext initialValue () {
88- StandardEvaluationContext context = new StandardEvaluationContext ();
89- context .addPropertyAccessor (accessor );
90- context .addMethodResolver (new ReflectiveMethodResolver () {
91- @ Override
92- public MethodExecutor resolve (@ Nonnull EvaluationContext context ,
93- @ Nonnull Object targetObject ,
94- @ Nonnull String name ,
95- @ Nonnull List <TypeDescriptor > argumentTypes ) throws AccessException {
96- return super .resolve (context , targetObject , name .toLowerCase (), argumentTypes );
97- }
98- });
99- context .setOperatorOverloader (new OperatorOverloader () {
100- @ Override
101- public boolean overridesOperation (@ Nonnull Operation operation , Object leftOperand , Object rightOperand ) throws EvaluationException {
102- if (leftOperand instanceof Number || rightOperand instanceof Number ) {
103- return leftOperand == null || rightOperand == null ;
104- }
105- return leftOperand == null && rightOperand == null ;
87+ static final Recycler <StandardEvaluationContext > SHARED_CONTEXT = Recycler .create (() -> {
88+ StandardEvaluationContext context = new StandardEvaluationContext ();
89+ context .addPropertyAccessor (accessor );
90+ context .addMethodResolver (new ReflectiveMethodResolver () {
91+ @ Override
92+ public MethodExecutor resolve (@ Nonnull EvaluationContext context ,
93+ @ Nonnull Object targetObject ,
94+ @ Nonnull String name ,
95+ @ Nonnull List <TypeDescriptor > argumentTypes ) throws AccessException {
96+ return super .resolve (context , targetObject , name .toLowerCase (), argumentTypes );
97+ }
98+ });
99+ context .setOperatorOverloader (new OperatorOverloader () {
100+ @ Override
101+ public boolean overridesOperation (@ Nonnull Operation operation , Object leftOperand , Object rightOperand ) throws EvaluationException {
102+ if (leftOperand instanceof Number || rightOperand instanceof Number ) {
103+ return leftOperand == null || rightOperand == null ;
106104 }
105+ return leftOperand == null && rightOperand == null ;
106+ }
107107
108- @ Override
109- public Object operate (@ Nonnull Operation operation , Object leftOperand , Object rightOperand ) throws EvaluationException {
110- return null ;
111- }
112- });
113- return context ;
114- }
115- };
108+ @ Override
109+ public Object operate (@ Nonnull Operation operation , Object leftOperand , Object rightOperand ) throws EvaluationException {
110+ return null ;
111+ }
112+ });
113+ return context ;
114+ }, ctx -> {
115+ }, 512 ) ;
116116
117117 @ Override
118118 protected Function3 <EntityColumnMapping , Object [], Map <String , Object >, Object > compile (String sql ) {
@@ -145,21 +145,24 @@ protected Function3<EntityColumnMapping, Object[], Map<String, Object>, Object>
145145 object .put ("_arg" + index , parameter );
146146 }
147147 }
148- StandardEvaluationContext context = SHARED_CONTEXT .get ();
149- try {
150- context .setRootObject (object );
151- Object val = expression .getValue (context );
152- errorCount .set (0 );
153- return val ;
154- } catch (Throwable err ) {
155- log .warn ("invoke native sql [{}] value error" ,
156- sql ,
157- err );
158- errorCount .incrementAndGet ();
159- } finally {
160- context .setRootObject (null );
161- }
162- return null ;
148+ return SHARED_CONTEXT .doWith (
149+ expression , object , errorCount , sql ,
150+ (context , expr , obj , cnt , _sql ) -> {
151+ try {
152+ context .setRootObject (obj );
153+ Object val = expr .getValue (context );
154+ cnt .set (0 );
155+ return val ;
156+ } catch (Throwable err ) {
157+ log .warn ("invoke native sql [{}] value error" ,
158+ _sql ,
159+ err );
160+ cnt .incrementAndGet ();
161+ } finally {
162+ context .setRootObject (null );
163+ }
164+ return null ;
165+ });
163166 };
164167 } catch (Throwable error ) {
165168 return spelError (sql , error );
@@ -175,8 +178,6 @@ protected Function3<EntityColumnMapping, Object[], Map<String, Object>, Object>
175178 return (mapping , args , data ) -> null ;
176179 }
177180
178- static ExtMapAccessor accessor = new ExtMapAccessor ();
179-
180181 static class ExtMapAccessor extends MapAccessor {
181182 @ Override
182183 public boolean canRead (@ Nonnull EvaluationContext context , Object target , @ Nonnull String name ) throws AccessException {
0 commit comments