diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java b/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java
index a83bf5dbe0..847da65a73 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelCompiler.java
+++ b/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");
* you may not use this file except in compliance with the License.
@@ -63,18 +63,20 @@ import org.springframework.util.StringUtils;
*
Individual expressions can be compiled by calling {@code SpelCompiler.compile(expression)}.
*
* @author Andy Clement
+ * @author Juergen Hoeller
* @since 4.1
*/
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 Log logger = LogFactory.getLog(SpelCompiler.class);
+
// 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.
private static final Map compilers = new ConcurrentReferenceHashMap<>();
+
// The child ClassLoader used to load the compiled expression classes
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
* 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.
* @param expression the expression to compile
* @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.
- * 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
* @return the expression call, or {@code null} if the decision was to opt out of
* compilation during code generation
@@ -150,7 +152,7 @@ public final class SpelCompiler implements Opcodes {
// Create getValue() method
mv = cw.visitMethod(ACC_PUBLIC, "getValue",
"(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();
CodeFlow cf = new CodeFlow(className, cw);
@@ -187,7 +189,7 @@ public final class SpelCompiler implements Opcodes {
/**
* 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
* at least some of the older variants can be garbage collected.
* @param name the name of the class
@@ -202,6 +204,7 @@ public final class SpelCompiler implements Opcodes {
return (Class extends CompiledExpression>) this.ccl.defineClass(name, bytes);
}
+
/**
* Factory method for compiler instances. The returned SpelCompiler will
* 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
- * components of the expression are not suitable for compilation or the data types
- * involved are not suitable for compilation. Used for testing.
- * @return true if the expression was successfully compiled
+ * Request that an attempt is made to compile the specified expression.
+ * It may fail if components of the expression are not suitable for compilation
+ * or the data types involved are not suitable for compilation. Used for testing.
+ * @param expression the expression to compile
+ * @return {@code true} if the expression was successfully compiled,
+ * {@code false} otherwise
*/
public static boolean compile(Expression expression) {
return (expression instanceof SpelExpression && ((SpelExpression) expression).compileExpression());
@@ -256,18 +261,21 @@ public final class SpelCompiler implements Opcodes {
super(NO_URLS, classLoader);
}
- int getClassesDefinedCount() {
- return this.classesDefinedCount;
- }
-
public Class> defineClass(String name, byte[] bytes) {
Class> clazz = super.defineClass(name, bytes, 0, bytes.length);
this.classesDefinedCount++;
return clazz;
}
+
+ public int getClassesDefinedCount() {
+ return this.classesDefinedCount;
+ }
}
+ /**
+ * An ASM ClassWriter extension bound to the SpelCompiler's ClassLoader.
+ */
private class ExpressionClassWriter extends ClassWriter {
public ExpressionClassWriter() {