Skip to content

Commit 11c0652

Browse files
authored
refactor: 增加新的Recycler工具来替代ThreadLocal对象池. (#334)
* refactor: 增加新的Recycler工具来替代ThreadLocal对象池. * refactor: 优化 * refactor(基础模块): 完善注释
1 parent fc9726d commit 11c0652

File tree

16 files changed

+1671
-184
lines changed

16 files changed

+1671
-184
lines changed

hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/expr/SpelSqlExpressionInvoker.java

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package org.hswebframework.web.crud.events.expr;
22

3-
import io.netty.util.concurrent.FastThreadLocal;
43
import jakarta.annotation.Nonnull;
54
import lombok.extern.slf4j.Slf4j;
65
import org.hswebframework.ezorm.rdb.mapping.EntityColumnMapping;
76
import org.hswebframework.web.crud.query.QueryHelperUtils;
7+
import org.hswebframework.web.recycler.Recycler;
88
import org.springframework.context.expression.MapAccessor;
99
import org.springframework.core.convert.TypeDescriptor;
1010
import org.springframework.expression.*;
@@ -20,6 +20,8 @@
2020
@Slf4j
2121
public 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 {

hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/query/QueryHelperUtils.java

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,56 @@
11
package org.hswebframework.web.crud.query;
22

3-
import io.netty.util.concurrent.FastThreadLocal;
43
import org.hswebframework.web.exception.BusinessException;
4+
import org.hswebframework.web.recycler.Recycler;
5+
import org.hswebframework.web.recycler.Recyclers;
56

67
public class QueryHelperUtils {
78

8-
static final FastThreadLocal<StringBuilder> SHARE = new FastThreadLocal<StringBuilder>() {
9-
@Override
10-
protected StringBuilder initialValue() throws Exception {
11-
return new StringBuilder();
12-
}
13-
};
9+
static final Recycler<StringBuilder> SHARE = Recyclers.STRING_BUILDER;
1410

1511
public static String toSnake(String col) {
16-
StringBuilder builder = SHARE.get();
17-
builder.setLength(0);
18-
for (int i = 0, len = col.length(); i < len; i++) {
19-
char c = col.charAt(i);
20-
if (Character.isUpperCase(c)) {
21-
if (i != 0) {
22-
builder.append('_');
12+
return SHARE.doWith(col, (builder, _col) -> {
13+
for (int i = 0, len = _col.length(); i < len; i++) {
14+
char c = _col.charAt(i);
15+
if (Character.isUpperCase(c)) {
16+
if (i != 0) {
17+
builder.append('_');
18+
}
19+
builder.append(Character.toLowerCase(c));
20+
} else {
21+
builder.append(c);
2322
}
24-
builder.append(Character.toLowerCase(c));
25-
} else {
26-
builder.append(c);
2723
}
28-
}
29-
return builder.toString();
24+
return builder.toString();
25+
});
3026
}
3127

3228
public static String toHump(String col) {
33-
StringBuilder builder = SHARE.get();
34-
builder.setLength(0);
35-
boolean hasUpper = false, hasLower = false;
36-
for (int i = 0, len = col.length(); i < len; i++) {
37-
char c = col.charAt(i);
38-
if (Character.isLowerCase(c)) {
39-
hasLower = true;
40-
}
41-
if (Character.isUpperCase(c)) {
42-
hasUpper = true;
43-
}
44-
if (hasUpper && hasLower) {
45-
return col;
46-
}
47-
if (c == '_') {
48-
if (i == len - 1) {
49-
builder.append('_');
29+
return SHARE.doWith(col, (builder, _col) -> {
30+
boolean hasUpper = false, hasLower = false;
31+
for (int i = 0, len = _col.length(); i < len; i++) {
32+
char c = _col.charAt(i);
33+
if (Character.isLowerCase(c)) {
34+
hasLower = true;
35+
}
36+
if (Character.isUpperCase(c)) {
37+
hasUpper = true;
38+
}
39+
if (hasUpper && hasLower) {
40+
return _col;
41+
}
42+
if (c == '_') {
43+
if (i == len - 1) {
44+
builder.append('_');
45+
} else {
46+
builder.append(Character.toUpperCase(_col.charAt(++i)));
47+
}
5048
} else {
51-
builder.append(Character.toUpperCase(col.charAt(++i)));
49+
builder.append(Character.toLowerCase(c));
5250
}
53-
} else {
54-
builder.append(Character.toLowerCase(c));
5551
}
56-
}
57-
return builder.toString();
58-
52+
return builder.toString();
53+
});
5954
}
6055

6156
public static void assertLegalColumn(String col) {
@@ -68,7 +63,7 @@ public static boolean isLegalColumn(String col) {
6863
int len = col.length();
6964
for (int i = 0; i < len; i++) {
7065
char c = col.charAt(i);
71-
if (c == '_' || c == '$' || Character.isLetterOrDigit(c)) {
66+
if (c == '_' || c == '$' || Character.isLetterOrDigit(c)) {
7267
continue;
7368
}
7469
return false;

0 commit comments

Comments
 (0)