Browse Source

Polishing

pull/23967/head
Juergen Hoeller 5 years ago
parent
commit
103f57a0a6
  1. 10
      spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java
  2. 9
      spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java
  3. 42
      spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java

10
spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -219,10 +219,12 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
@Override @Override
@Nullable @Nullable
public String[] getParameterNames() { public String[] getParameterNames() {
if (this.parameterNames == null) { String[] parameterNames = this.parameterNames;
this.parameterNames = parameterNameDiscoverer.getParameterNames(getMethod()); if (parameterNames == null) {
parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
this.parameterNames = parameterNames;
} }
return this.parameterNames; return parameterNames;
} }
@Override @Override

9
spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -52,7 +52,7 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
/** /**
* Create a new DirectFieldAccessor for the given object. * Create a new DirectFieldAccessor for the given object.
* @param object object wrapped by this DirectFieldAccessor * @param object the object wrapped by this DirectFieldAccessor
*/ */
public DirectFieldAccessor(Object object) { public DirectFieldAccessor(Object object) {
super(object); super(object);
@ -61,7 +61,7 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
/** /**
* Create a new DirectFieldAccessor for the given object, * Create a new DirectFieldAccessor for the given object,
* registering a nested path that the object is in. * registering a nested path that the object is in.
* @param object object wrapped by this DirectFieldAccessor * @param object the object wrapped by this DirectFieldAccessor
* @param nestedPath the nested path of the object * @param nestedPath the nested path of the object
* @param parent the containing DirectFieldAccessor (must not be {@code null}) * @param parent the containing DirectFieldAccessor (must not be {@code null})
*/ */
@ -92,8 +92,7 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor {
@Override @Override
protected NotWritablePropertyException createNotWritablePropertyException(String propertyName) { protected NotWritablePropertyException createNotWritablePropertyException(String propertyName) {
PropertyMatches matches = PropertyMatches.forField(propertyName, getRootClass()); PropertyMatches matches = PropertyMatches.forField(propertyName, getRootClass());
throw new NotWritablePropertyException( throw new NotWritablePropertyException(getRootClass(), getNestedPath() + propertyName,
getRootClass(), getNestedPath() + propertyName,
matches.buildErrorMessage(), matches.getPossibleMatches()); matches.buildErrorMessage(), matches.getPossibleMatches());
} }

42
spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -63,18 +63,20 @@ import org.springframework.util.StringUtils;
* <p>Individual expressions can be compiled by calling {@code SpelCompiler.compile(expression)}. * <p>Individual expressions can be compiled by calling {@code SpelCompiler.compile(expression)}.
* *
* @author Andy Clement * @author Andy Clement
* @author Juergen Hoeller
* @since 4.1 * @since 4.1
*/ */
public final class SpelCompiler implements Opcodes { public final class SpelCompiler implements Opcodes {
private static final Log logger = LogFactory.getLog(SpelCompiler.class);
private static final int CLASSES_DEFINED_LIMIT = 100; private static final int CLASSES_DEFINED_LIMIT = 100;
private static final Log logger = LogFactory.getLog(SpelCompiler.class);
// A compiler is created for each classloader, it manages a child class loader of that // A compiler is created for each classloader, it manages a child class loader of that
// classloader and the child is used to load the compiled expressions. // classloader and the child is used to load the compiled expressions.
private static final Map<ClassLoader, SpelCompiler> compilers = new ConcurrentReferenceHashMap<>(); private static final Map<ClassLoader, SpelCompiler> compilers = new ConcurrentReferenceHashMap<>();
// The child ClassLoader used to load the compiled expression classes // The child ClassLoader used to load the compiled expression classes
private ChildClassLoader ccl; private ChildClassLoader ccl;
@ -90,7 +92,7 @@ public final class SpelCompiler implements Opcodes {
/** /**
* Attempt compilation of the supplied expression. A check is made to see * Attempt compilation of the supplied expression. A check is made to see
* if it is compilable before compilation proceeds. The check involves * if it is compilable before compilation proceeds. The check involves
* visiting all the nodes in the expression Ast and ensuring enough state * visiting all the nodes in the expression AST and ensuring enough state
* is known about them that bytecode can be generated for them. * is known about them that bytecode can be generated for them.
* @param expression the expression to compile * @param expression the expression to compile
* @return an instance of the class implementing the compiled expression, * @return an instance of the class implementing the compiled expression,
@ -125,7 +127,7 @@ public final class SpelCompiler implements Opcodes {
/** /**
* Generate the class that encapsulates the compiled expression and define it. * Generate the class that encapsulates the compiled expression and define it.
* The generated class will be a subtype of CompiledExpression. * The generated class will be a subtype of CompiledExpression.
* @param expressionToCompile the expression to be compiled * @param expressionToCompile the expression to be compiled
* @return the expression call, or {@code null} if the decision was to opt out of * @return the expression call, or {@code null} if the decision was to opt out of
* compilation during code generation * compilation during code generation
@ -150,7 +152,7 @@ public final class SpelCompiler implements Opcodes {
// Create getValue() method // Create getValue() method
mv = cw.visitMethod(ACC_PUBLIC, "getValue", mv = cw.visitMethod(ACC_PUBLIC, "getValue",
"(Ljava/lang/Object;Lorg/springframework/expression/EvaluationContext;)Ljava/lang/Object;", null, "(Ljava/lang/Object;Lorg/springframework/expression/EvaluationContext;)Ljava/lang/Object;", null,
new String[ ]{"org/springframework/expression/EvaluationException"}); new String[] {"org/springframework/expression/EvaluationException"});
mv.visitCode(); mv.visitCode();
CodeFlow cf = new CodeFlow(className, cw); CodeFlow cf = new CodeFlow(className, cw);
@ -187,11 +189,11 @@ public final class SpelCompiler implements Opcodes {
/** /**
* Load a compiled expression class. Makes sure the classloaders aren't used too much * Load a compiled expression class. Makes sure the classloaders aren't used too much
* because they anchor compiled classes in memory and prevent GC. If you have expressions * because they anchor compiled classes in memory and prevent GC. If you have expressions
* continually recompiling over time then by replacing the classloader periodically * continually recompiling over time then by replacing the classloader periodically
* at least some of the older variants can be garbage collected. * at least some of the older variants can be garbage collected.
* @param name name of the class * @param name the name of the class
* @param bytes bytecode for the class * @param bytes the bytecode for the class
* @return the Class object for the compiled expression * @return the Class object for the compiled expression
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -202,6 +204,7 @@ public final class SpelCompiler implements Opcodes {
return (Class<? extends CompiledExpression>) this.ccl.defineClass(name, bytes); return (Class<? extends CompiledExpression>) this.ccl.defineClass(name, bytes);
} }
/** /**
* Factory method for compiler instances. The returned SpelCompiler will * Factory method for compiler instances. The returned SpelCompiler will
* attach a class loader as the child of the given class loader and this * attach a class loader as the child of the given class loader and this
@ -222,10 +225,12 @@ public final class SpelCompiler implements Opcodes {
} }
/** /**
* Request that an attempt is made to compile the specified expression. It may fail if * Request that an attempt is made to compile the specified expression.
* components of the expression are not suitable for compilation or the data types * It may fail if components of the expression are not suitable for compilation
* involved are not suitable for compilation. Used for testing. * or the data types involved are not suitable for compilation. Used for testing.
* @return true if the expression was successfully compiled * @param expression the expression to compile
* @return {@code true} if the expression was successfully compiled,
* {@code false} otherwise
*/ */
public static boolean compile(Expression expression) { public static boolean compile(Expression expression) {
return (expression instanceof SpelExpression && ((SpelExpression) expression).compileExpression()); return (expression instanceof SpelExpression && ((SpelExpression) expression).compileExpression());
@ -256,18 +261,21 @@ public final class SpelCompiler implements Opcodes {
super(NO_URLS, classLoader); super(NO_URLS, classLoader);
} }
int getClassesDefinedCount() {
return this.classesDefinedCount;
}
public Class<?> defineClass(String name, byte[] bytes) { public Class<?> defineClass(String name, byte[] bytes) {
Class<?> clazz = super.defineClass(name, bytes, 0, bytes.length); Class<?> clazz = super.defineClass(name, bytes, 0, bytes.length);
this.classesDefinedCount++; this.classesDefinedCount++;
return clazz; return clazz;
} }
public int getClassesDefinedCount() {
return this.classesDefinedCount;
}
} }
/**
* An ASM ClassWriter extension bound to the SpelCompiler's ClassLoader.
*/
private class ExpressionClassWriter extends ClassWriter { private class ExpressionClassWriter extends ClassWriter {
public ExpressionClassWriter() { public ExpressionClassWriter() {

Loading…
Cancel
Save