Polishing
This commit is contained in:
parent
356ef45e99
commit
3988dd9ebb
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -64,8 +64,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
|||
|
||||
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<>(256);
|
||||
|
||||
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
|
||||
new ConcurrentHashMap<>(8);
|
||||
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache = new ConcurrentHashMap<>(8);
|
||||
|
||||
private final ParserContext beanExpressionParserContext = new ParserContext() {
|
||||
@Override
|
||||
|
|
@ -145,8 +144,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
|||
}
|
||||
StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
|
||||
if (sec == null) {
|
||||
sec = new StandardEvaluationContext();
|
||||
sec.setRootObject(evalContext);
|
||||
sec = new StandardEvaluationContext(evalContext);
|
||||
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
|
||||
sec.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
sec.addPropertyAccessor(new MapAccessor());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -57,7 +57,8 @@ public class MethodReference extends SpelNodeImpl {
|
|||
|
||||
private final boolean nullSafe;
|
||||
|
||||
private String originalPrimitiveExitTypeDescriptor = null;
|
||||
@Nullable
|
||||
private String originalPrimitiveExitTypeDescriptor;
|
||||
|
||||
@Nullable
|
||||
private volatile CachedMethodExecutor cachedExecutor;
|
||||
|
|
@ -311,11 +312,11 @@ public class MethodReference extends SpelNodeImpl {
|
|||
// Nothing on the stack but something is needed
|
||||
cf.loadTarget(mv);
|
||||
}
|
||||
if ((descriptor != null || !isStaticMethod) && nullSafe) {
|
||||
if ((descriptor != null || !isStaticMethod) && this.nullSafe) {
|
||||
mv.visitInsn(DUP);
|
||||
skipIfNull = new Label();
|
||||
Label continueLabel = new Label();
|
||||
mv.visitJumpInsn(IFNONNULL,continueLabel);
|
||||
mv.visitJumpInsn(IFNONNULL, continueLabel);
|
||||
CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor);
|
||||
mv.visitJumpInsn(GOTO, skipIfNull);
|
||||
mv.visitLabel(continueLabel);
|
||||
|
|
@ -329,7 +330,7 @@ public class MethodReference extends SpelNodeImpl {
|
|||
CodeFlow.insertBoxIfNecessary(mv, descriptor.charAt(0));
|
||||
}
|
||||
|
||||
String classDesc = null;
|
||||
String classDesc;
|
||||
if (Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
|
||||
classDesc = method.getDeclaringClass().getName().replace('.', '/');
|
||||
}
|
||||
|
|
@ -339,20 +340,19 @@ public class MethodReference extends SpelNodeImpl {
|
|||
classDesc = publicDeclaringClass.getName().replace('.', '/');
|
||||
}
|
||||
|
||||
if (!isStaticMethod) {
|
||||
if (descriptor == null || !descriptor.substring(1).equals(classDesc)) {
|
||||
CodeFlow.insertCheckCast(mv, "L" + classDesc);
|
||||
}
|
||||
if (!isStaticMethod && (descriptor == null || !descriptor.substring(1).equals(classDesc))) {
|
||||
CodeFlow.insertCheckCast(mv, "L" + classDesc);
|
||||
}
|
||||
|
||||
generateCodeForArguments(mv, cf, method, this.children);
|
||||
mv.visitMethodInsn((isStaticMethod ? INVOKESTATIC : INVOKEVIRTUAL), classDesc, method.getName(),
|
||||
CodeFlow.createSignatureDescriptor(method), method.getDeclaringClass().isInterface());
|
||||
cf.pushDescriptor(this.exitTypeDescriptor);
|
||||
if (originalPrimitiveExitTypeDescriptor != null) {
|
||||
|
||||
if (this.originalPrimitiveExitTypeDescriptor != null) {
|
||||
// The output of the accessor will be a primitive but from the block above it might be null,
|
||||
// so to have a 'common stack' element at skipIfNull target we need to box the primitive
|
||||
CodeFlow.insertBoxIfNecessary(mv, originalPrimitiveExitTypeDescriptor);
|
||||
CodeFlow.insertBoxIfNecessary(mv, this.originalPrimitiveExitTypeDescriptor);
|
||||
}
|
||||
if (skipIfNull != null) {
|
||||
mv.visitLabel(skipIfNull);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -52,10 +52,11 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
|
|||
|
||||
private final boolean nullSafe;
|
||||
|
||||
private String originalPrimitiveExitTypeDescriptor = null;
|
||||
|
||||
private final String name;
|
||||
|
||||
@Nullable
|
||||
private String originalPrimitiveExitTypeDescriptor;
|
||||
|
||||
@Nullable
|
||||
private volatile PropertyAccessor cachedReadAccessor;
|
||||
|
||||
|
|
@ -341,23 +342,26 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
|
|||
if (!(accessorToUse instanceof CompilablePropertyAccessor)) {
|
||||
throw new IllegalStateException("Property accessor is not compilable: " + accessorToUse);
|
||||
}
|
||||
|
||||
Label skipIfNull = null;
|
||||
if (nullSafe) {
|
||||
if (this.nullSafe) {
|
||||
mv.visitInsn(DUP);
|
||||
skipIfNull = new Label();
|
||||
Label continueLabel = new Label();
|
||||
mv.visitJumpInsn(IFNONNULL,continueLabel);
|
||||
mv.visitJumpInsn(IFNONNULL, continueLabel);
|
||||
CodeFlow.insertCheckCast(mv, this.exitTypeDescriptor);
|
||||
mv.visitJumpInsn(GOTO, skipIfNull);
|
||||
mv.visitLabel(continueLabel);
|
||||
}
|
||||
|
||||
((CompilablePropertyAccessor) accessorToUse).generateCode(this.name, mv, cf);
|
||||
cf.pushDescriptor(this.exitTypeDescriptor);
|
||||
if (originalPrimitiveExitTypeDescriptor != null) {
|
||||
|
||||
if (this.originalPrimitiveExitTypeDescriptor != null) {
|
||||
// The output of the accessor is a primitive but from the block above it might be null,
|
||||
// so to have a common stack element type at skipIfNull target it is necessary
|
||||
// to box the primitive
|
||||
CodeFlow.insertBoxIfNecessary(mv, originalPrimitiveExitTypeDescriptor);
|
||||
CodeFlow.insertBoxIfNecessary(mv, this.originalPrimitiveExitTypeDescriptor);
|
||||
}
|
||||
if (skipIfNull != null) {
|
||||
mv.visitLabel(skipIfNull);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ import org.springframework.util.Assert;
|
|||
*/
|
||||
public class StandardEvaluationContext implements EvaluationContext {
|
||||
|
||||
private TypedValue rootObject = TypedValue.NULL;
|
||||
private TypedValue rootObject;
|
||||
|
||||
@Nullable
|
||||
private volatile List<PropertyAccessor> propertyAccessors;
|
||||
|
|
@ -87,12 +87,20 @@ public class StandardEvaluationContext implements EvaluationContext {
|
|||
private final Map<String, Object> variables = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@code StandardEvaluationContext} with a null root object.
|
||||
*/
|
||||
public StandardEvaluationContext() {
|
||||
setRootObject(null);
|
||||
this.rootObject = TypedValue.NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code StandardEvaluationContext} with the given root object.
|
||||
* @param rootObject the root object to use
|
||||
* @see #setRootObject
|
||||
*/
|
||||
public StandardEvaluationContext(Object rootObject) {
|
||||
setRootObject(rootObject);
|
||||
this.rootObject = new TypedValue(rootObject);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue