mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-17 08:24:13 +00:00
Deprecate SpelParserConfiguration constructors in favor of the builder API
Since we now have an official builder API for SpelParserConfiguration
(introduced in 7.0.10), this commit follows through on the plan stated
in that commit's Javadoc and formally deprecates all 9 overloaded
constructors in SpelParserConfiguration, thereby encouraging users to
benefit from the simplicity of the builder API -- or
SpelParserConfiguration.withDefaults() for the common case -- instead
of having to migrate to the latest-and-greatest full constructor every
time a new configuration property is introduced.
The no-arg constructor points users to withDefaults(), and all other
constructors -- including the canonical 9-parameter constructor --
point to the builder API. Builder.build() has been annotated with
@SuppressWarnings("deprecation"), since it is the sole legitimate
internal caller of the now-deprecated canonical constructor.
The SpelParserConfigurationTests.LegacyConstructorTests nested class
(and its sibling builderAppliesSameDefaultsAsNoArgConstructor() test
method) are annotated with @SuppressWarnings("deprecation"), since they
exist specifically to provide regression coverage for the deprecated
constructors. IndexingTests.MaxAutoGrowSizeTests and
SpelParserTests.MaxNestingDepthTests, on the other hand, were both
introduced before the builder API existed and had no such need for the
legacy constructors, so they have been converted to use the builder API
instead, avoiding the need for any deprecation suppression there.
See gh-37187
Closes gh-37190
This commit is contained in:
+21
-2
@@ -32,8 +32,8 @@ import org.springframework.util.StringUtils;
|
||||
* configure and create a {@code SpelParserConfiguration} instance, since the
|
||||
* builder only requires configuration of the properties that need to deviate from
|
||||
* their sensible defaults — or use {@link #withDefaults()} if none of those
|
||||
* defaults need to be overridden. Note that the constructors in this class are
|
||||
* planned to be deprecated in favor of the builder as of Spring Framework 7.1.
|
||||
* defaults need to be overridden. Note that the constructors in this class have
|
||||
* been deprecated in favor of the builder as of Spring Framework 7.1.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
@@ -205,7 +205,9 @@ public class SpelParserConfiguration {
|
||||
* @see #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME
|
||||
* @see #DEFAULT_MAX_AUTO_GROW_SIZE
|
||||
* @deprecated as of Spring Framework 7.1, in favor of {@link #withDefaults()}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration() {
|
||||
this(null, null);
|
||||
}
|
||||
@@ -223,7 +225,9 @@ public class SpelParserConfiguration {
|
||||
* @see #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME
|
||||
* @see #DEFAULT_MAX_AUTO_GROW_SIZE
|
||||
* @deprecated as of Spring Framework 7.1, in favor of the {@linkplain #builder() builder API}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration(@Nullable SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader) {
|
||||
this(compilerMode, compilerClassLoader, false, false, DEFAULT_MAX_AUTO_GROW_SIZE);
|
||||
}
|
||||
@@ -239,7 +243,9 @@ public class SpelParserConfiguration {
|
||||
* @see #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME
|
||||
* @see #DEFAULT_MAX_AUTO_GROW_SIZE
|
||||
* @deprecated as of Spring Framework 7.1, in favor of the {@linkplain #builder() builder API}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections) {
|
||||
this(autoGrowNullReferences, autoGrowCollections, DEFAULT_MAX_AUTO_GROW_SIZE);
|
||||
}
|
||||
@@ -257,7 +263,9 @@ public class SpelParserConfiguration {
|
||||
* @see #SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME
|
||||
* @deprecated as of Spring Framework 7.1, in favor of the {@linkplain #builder() builder API}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize) {
|
||||
this(null, null, autoGrowNullReferences, autoGrowCollections, maximumAutoGrowSize);
|
||||
}
|
||||
@@ -279,7 +287,9 @@ public class SpelParserConfiguration {
|
||||
* @see #SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME
|
||||
* @deprecated as of Spring Framework 7.1, in favor of the {@linkplain #builder() builder API}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration(@Nullable SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader,
|
||||
boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize) {
|
||||
|
||||
@@ -308,7 +318,9 @@ public class SpelParserConfiguration {
|
||||
* @see #SPRING_EXPRESSION_MAX_OPERATIONS_PROPERTY_NAME
|
||||
* @see #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME
|
||||
* @see #DEFAULT_MAX_EXPRESSION_NESTING_DEPTH
|
||||
* @deprecated as of Spring Framework 7.1, in favor of the {@linkplain #builder() builder API}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration(@Nullable SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader,
|
||||
boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize, int maximumExpressionLength) {
|
||||
|
||||
@@ -337,7 +349,9 @@ public class SpelParserConfiguration {
|
||||
* @since 6.2.19
|
||||
* @see #SPRING_EXPRESSION_MAX_BIG_POWER_BITS_PROPERTY_NAME
|
||||
* @see #DEFAULT_MAX_EXPRESSION_NESTING_DEPTH
|
||||
* @deprecated as of Spring Framework 7.1, in favor of the {@linkplain #builder() builder API}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration(SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader,
|
||||
boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize, int maximumExpressionLength,
|
||||
int maximumOperations) {
|
||||
@@ -369,7 +383,9 @@ public class SpelParserConfiguration {
|
||||
* operation; must be a positive number; use {@link Integer#MAX_VALUE} for no limit
|
||||
* @since 7.0.9
|
||||
* @see #DEFAULT_MAX_EXPRESSION_NESTING_DEPTH
|
||||
* @deprecated as of Spring Framework 7.1, in favor of the {@linkplain #builder() builder API}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration(SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader,
|
||||
boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize, int maximumExpressionLength,
|
||||
int maximumOperations, int maximumBigPowerBits) {
|
||||
@@ -402,7 +418,9 @@ public class SpelParserConfiguration {
|
||||
* @param maximumNestingDepth the maximum nesting depth permitted within a SpEL
|
||||
* expression; must be a positive number
|
||||
* @since 7.1
|
||||
* @deprecated as of Spring Framework 7.1, in favor of the {@linkplain #builder() builder API}
|
||||
*/
|
||||
@Deprecated(since = "7.1")
|
||||
public SpelParserConfiguration(SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader,
|
||||
boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize, int maximumExpressionLength,
|
||||
int maximumOperations, int maximumBigPowerBits, int maximumNestingDepth) {
|
||||
@@ -690,6 +708,7 @@ public class SpelParserConfiguration {
|
||||
/**
|
||||
* Build the {@link SpelParserConfiguration} configured via this builder.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public SpelParserConfiguration build() {
|
||||
int maximumOperations = (this.maximumOperations != null ?
|
||||
this.maximumOperations : retrieveMaxOperations());
|
||||
|
||||
+9
-5
@@ -340,7 +340,8 @@ class IndexingTests {
|
||||
|
||||
@Test
|
||||
void defaultMaxAutoGrowSizeMatchesDataBinderDefault() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelParserConfiguration configuration =
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build();
|
||||
assertThat(configuration.getMaximumAutoGrowSize())
|
||||
.isEqualTo(SpelParserConfiguration.DEFAULT_MAX_AUTO_GROW_SIZE)
|
||||
.isEqualTo(256);
|
||||
@@ -349,7 +350,8 @@ class IndexingTests {
|
||||
@Test
|
||||
void zeroMaximumAutoGrowSizeIsAllowedAndDisablesGrowth() {
|
||||
decimals = new ArrayList<>();
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true, 0);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder()
|
||||
.autoGrowNullReferences().autoGrowCollections().maximumAutoGrowSize(0).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
|
||||
Expression indexExpression = parser.parseExpression("decimals[0]");
|
||||
@@ -361,14 +363,15 @@ class IndexingTests {
|
||||
@Test
|
||||
void negativeMaximumAutoGrowSizeIsRejected() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new SpelParserConfiguration(true, true, -1))
|
||||
.isThrownBy(() -> SpelParserConfiguration.builder().maximumAutoGrowSize(-1))
|
||||
.withMessage("'maximumAutoGrowSize' must not be negative");
|
||||
}
|
||||
|
||||
@Test
|
||||
void collectionGrowsUpToDefaultMaxAutoGrowSizeButNotBeyond() {
|
||||
decimals = new ArrayList<>();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
SpelExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().autoGrowNullReferences().autoGrowCollections().build());
|
||||
|
||||
// Growing up to the default maximum auto-grow size should succeed.
|
||||
parser.parseExpression("decimals[255]").getValue(IndexingTests.this);
|
||||
@@ -384,7 +387,8 @@ class IndexingTests {
|
||||
@Test
|
||||
void collectionCanGrowBeyondDefaultMaxAutoGrowSizeWhenConfiguredExplicitly() {
|
||||
decimals = new ArrayList<>();
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true, 1000);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder()
|
||||
.autoGrowNullReferences().autoGrowCollections().maximumAutoGrowSize(1000).build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
|
||||
parser.parseExpression("decimals[500]").getValue(IndexingTests.this);
|
||||
|
||||
+2
@@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class SpelParserConfigurationTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void builderAppliesSameDefaultsAsNoArgConstructor() {
|
||||
SpelParserConfiguration expected = new SpelParserConfiguration();
|
||||
SpelParserConfiguration actual = SpelParserConfiguration.builder().build();
|
||||
@@ -110,6 +111,7 @@ class SpelParserConfigurationTests {
|
||||
* these constructors confined to this class.
|
||||
*/
|
||||
@Nested
|
||||
@SuppressWarnings("deprecation")
|
||||
class LegacyConstructorTests {
|
||||
|
||||
@Test
|
||||
|
||||
+6
-11
@@ -65,7 +65,8 @@ class SpelParserTests {
|
||||
|
||||
private final int maxNestingDepth = 10;
|
||||
|
||||
private final SpelExpressionParser parser = new SpelExpressionParser(configurationWithMaxNestingDepth(maxNestingDepth));
|
||||
private final SpelExpressionParser parser = new SpelExpressionParser(
|
||||
SpelParserConfiguration.builder().maximumNestingDepth(maxNestingDepth).build());
|
||||
|
||||
|
||||
@Test
|
||||
@@ -103,10 +104,10 @@ class SpelParserTests {
|
||||
void maxNestingDepthProtectsAgainstStackOverflowFromChainedUnaryOperators() {
|
||||
// Effectively disable the expression-length limit so that the nesting-depth
|
||||
// limit is the guard that stops the parser well before the JVM call stack does.
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false,
|
||||
0, Integer.MAX_VALUE, SpelParserConfiguration.DEFAULT_MAX_OPERATIONS,
|
||||
SpelParserConfiguration.DEFAULT_MAX_BIG_POWER_BITS,
|
||||
SpelParserConfiguration.DEFAULT_MAX_EXPRESSION_NESTING_DEPTH);
|
||||
SpelParserConfiguration configuration = SpelParserConfiguration.builder()
|
||||
.compilerMode(SpelCompilerMode.OFF)
|
||||
.maximumExpressionLength(Integer.MAX_VALUE)
|
||||
.build();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
|
||||
assertParseExceptionThrownBy(() -> parser.parseExpression("!".repeat(100_000) + "true"))
|
||||
@@ -129,12 +130,6 @@ class SpelParserTests {
|
||||
assertNestingDepthExceeded(() -> parser.parseExpression(nestedTernaryExpression(50)), maxNestingDepth);
|
||||
}
|
||||
|
||||
private static SpelParserConfiguration configurationWithMaxNestingDepth(int maxNestingDepth) {
|
||||
return new SpelParserConfiguration(SpelCompilerMode.OFF, null, false, false, 0, 10_000,
|
||||
SpelParserConfiguration.DEFAULT_MAX_OPERATIONS, SpelParserConfiguration.DEFAULT_MAX_BIG_POWER_BITS,
|
||||
maxNestingDepth);
|
||||
}
|
||||
|
||||
private static void assertNestingDepthExceeded(ThrowingCallable throwingCallable, int maxNestingDepth) {
|
||||
assertParseExceptionThrownBy(throwingCallable)
|
||||
.withMessageEndingWith("SpEL expression nesting depth exceeds the threshold of " + maxNestingDepth)
|
||||
|
||||
Reference in New Issue
Block a user