Skip to content

Commit a8adec7

Browse files
committed
Avoid unnecessary creation of default StandardEnvironment instances
Issue: SPR-10568 (cherry picked from commit 7e01578)
1 parent 2ae61c5 commit a8adec7

File tree

7 files changed

+136
-114
lines changed

7 files changed

+136
-114
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinitionReader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
5454

5555
private ClassLoader beanClassLoader;
5656

57-
private Environment environment = new StandardEnvironment();
57+
private Environment environment;
5858

5959
private BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator();
6060

@@ -90,7 +90,7 @@ protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
9090

9191
// Inherit Environment if possible
9292
if (this.registry instanceof EnvironmentCapable) {
93-
this.environment = ((EnvironmentCapable)this.registry).getEnvironment();
93+
this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
9494
}
9595
else {
9696
this.environment = new StandardEnvironment();

spring-beans/src/main/java/org/springframework/beans/support/ResourceEditorRegistrar.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -78,9 +78,12 @@ public ResourceEditorRegistrar(ResourceLoader resourceLoader) {
7878
}
7979

8080
/**
81-
* Create a new ResourceEditorRegistrar for the given ResourceLoader
81+
* Create a new ResourceEditorRegistrar for the given {@link ResourceLoader}
82+
* and {@link PropertyResolver}.
8283
* @param resourceLoader the ResourceLoader (or ResourcePatternResolver)
8384
* to create editors for (usually an ApplicationContext)
85+
* @param propertyResolver the PropertyResolver (usually an Environment)
86+
* @see org.springframework.core.env.Environment
8487
* @see org.springframework.core.io.support.ResourcePatternResolver
8588
* @see org.springframework.context.ApplicationContext
8689
*/

spring-context/src/main/java/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -90,7 +90,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
9090

9191

9292
/**
93-
* Create a ClassPathScanningCandidateComponentProvider.
93+
* Create a ClassPathScanningCandidateComponentProvider with a {@link StandardEnvironment}.
9494
* @param useDefaultFilters whether to register the default filters for the
9595
* {@link Component @Component}, {@link Repository @Repository},
9696
* {@link Service @Service}, and {@link Controller @Controller}
@@ -101,6 +101,15 @@ public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters) {
101101
this(useDefaultFilters, new StandardEnvironment());
102102
}
103103

104+
/**
105+
* Create a ClassPathScanningCandidateComponentProvider with the given {@link Environment}.
106+
* @param useDefaultFilters whether to register the default filters for the
107+
* {@link Component @Component}, {@link Repository @Repository},
108+
* {@link Service @Service}, and {@link Controller @Controller}
109+
* stereotype annotations
110+
* @param environment the Environment to use
111+
* @see #registerDefaultFilters()
112+
*/
104113
public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) {
105114
if (useDefaultFilters) {
106115
registerDefaultFilters();

spring-core/src/main/java/org/springframework/core/env/AbstractEnvironment.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -437,7 +437,7 @@ public <T> T getProperty(String key, Class<T> targetType) {
437437

438438
public <T> T getProperty(String key, Class<T> targetType, T defaultValue) {
439439
return this.propertyResolver.getProperty(key, targetType, defaultValue);
440-
};
440+
}
441441

442442
public <T> Class<T> getPropertyAsClass(String key, Class<T> targetType) {
443443
return this.propertyResolver.getPropertyAsClass(key, targetType);
Lines changed: 68 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.core.env;
1818

19-
import static java.lang.String.format;
20-
2119
import org.springframework.core.convert.ConversionException;
2220
import org.springframework.util.ClassUtils;
2321

@@ -35,6 +33,7 @@ public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
3533

3634
private final PropertySources propertySources;
3735

36+
3837
/**
3938
* Create a new resolver against the given property sources.
4039
* @param propertySources the set of {@link PropertySource} objects to use
@@ -43,106 +42,110 @@ public PropertySourcesPropertyResolver(PropertySources propertySources) {
4342
this.propertySources = propertySources;
4443
}
4544

45+
46+
@Override
4647
public boolean containsProperty(String key) {
47-
for (PropertySource<?> propertySource : this.propertySources) {
48-
if (propertySource.containsProperty(key)) {
49-
return true;
48+
if (this.propertySources != null) {
49+
for (PropertySource<?> propertySource : this.propertySources) {
50+
if (propertySource.containsProperty(key)) {
51+
return true;
52+
}
5053
}
5154
}
5255
return false;
5356
}
5457

58+
@Override
5559
public String getProperty(String key) {
56-
if (logger.isTraceEnabled()) {
57-
logger.trace(format("getProperty(\"%s\") (implicit targetType [String])", key));
58-
}
59-
return this.getProperty(key, String.class);
60+
return getProperty(key, String.class);
6061
}
6162

63+
@Override
6264
public <T> T getProperty(String key, Class<T> targetValueType) {
6365
boolean debugEnabled = logger.isDebugEnabled();
6466
if (logger.isTraceEnabled()) {
65-
logger.trace(format("getProperty(\"%s\", %s)", key, targetValueType.getSimpleName()));
67+
logger.trace(String.format("getProperty(\"%s\", %s)", key, targetValueType.getSimpleName()));
6668
}
67-
68-
for (PropertySource<?> propertySource : this.propertySources) {
69-
if (debugEnabled) {
70-
logger.debug(format("Searching for key '%s' in [%s]", key, propertySource.getName()));
71-
}
72-
Object value;
73-
if ((value = propertySource.getProperty(key)) != null) {
74-
Class<?> valueType = value.getClass();
75-
if (String.class.equals(valueType)) {
76-
value = this.resolveNestedPlaceholders((String) value);
77-
}
69+
if (this.propertySources != null) {
70+
for (PropertySource<?> propertySource : this.propertySources) {
7871
if (debugEnabled) {
79-
logger.debug(
80-
format("Found key '%s' in [%s] with type [%s] and value '%s'",
81-
key, propertySource.getName(), valueType.getSimpleName(), value));
72+
logger.debug(String.format("Searching for key '%s' in [%s]", key, propertySource.getName()));
8273
}
83-
if (!this.conversionService.canConvert(valueType, targetValueType)) {
84-
throw new IllegalArgumentException(
85-
format("Cannot convert value [%s] from source type [%s] to target type [%s]",
86-
value, valueType.getSimpleName(), targetValueType.getSimpleName()));
74+
Object value;
75+
if ((value = propertySource.getProperty(key)) != null) {
76+
Class<?> valueType = value.getClass();
77+
if (String.class.equals(valueType)) {
78+
value = this.resolveNestedPlaceholders((String) value);
79+
}
80+
if (debugEnabled) {
81+
logger.debug(String.format("Found key '%s' in [%s] with type [%s] and value '%s'",
82+
key, propertySource.getName(), valueType.getSimpleName(), value));
83+
}
84+
if (!this.conversionService.canConvert(valueType, targetValueType)) {
85+
throw new IllegalArgumentException(String.format(
86+
"Cannot convert value [%s] from source type [%s] to target type [%s]",
87+
value, valueType.getSimpleName(), targetValueType.getSimpleName()));
88+
}
89+
return conversionService.convert(value, targetValueType);
8790
}
88-
return conversionService.convert(value, targetValueType);
8991
}
9092
}
91-
9293
if (debugEnabled) {
93-
logger.debug(format("Could not find key '%s' in any property source. Returning [null]", key));
94+
logger.debug(String.format("Could not find key '%s' in any property source. Returning [null]", key));
9495
}
9596
return null;
9697
}
9798

99+
@Override
98100
public <T> Class<T> getPropertyAsClass(String key, Class<T> targetValueType) {
99101
boolean debugEnabled = logger.isDebugEnabled();
100102
if (logger.isTraceEnabled()) {
101-
logger.trace(format("getPropertyAsClass(\"%s\", %s)", key, targetValueType.getSimpleName()));
103+
logger.trace(String.format("getPropertyAsClass(\"%s\", %s)", key, targetValueType.getSimpleName()));
102104
}
103-
104-
for (PropertySource<?> propertySource : this.propertySources) {
105-
if (debugEnabled) {
106-
logger.debug(format("Searching for key '%s' in [%s]", key, propertySource.getName()));
107-
}
108-
Object value;
109-
if ((value = propertySource.getProperty(key)) != null) {
105+
if (this.propertySources != null) {
106+
for (PropertySource<?> propertySource : this.propertySources) {
110107
if (debugEnabled) {
111-
logger.debug(
112-
format("Found key '%s' in [%s] with value '%s'", key, propertySource.getName(), value));
108+
logger.debug(String.format("Searching for key '%s' in [%s]", key, propertySource.getName()));
113109
}
114-
115-
Class<?> clazz;
116-
if (value instanceof String) {
117-
try {
118-
clazz = ClassUtils.forName((String)value, null);
119-
} catch (Exception ex) {
120-
throw new ClassConversionException((String)value, targetValueType, ex);
110+
Object value = propertySource.getProperty(key);
111+
if (value != null) {
112+
if (debugEnabled) {
113+
logger.debug(String.format("Found key '%s' in [%s] with value '%s'", key, propertySource.getName(), value));
121114
}
115+
Class<?> clazz;
116+
if (value instanceof String) {
117+
try {
118+
clazz = ClassUtils.forName((String)value, null);
119+
}
120+
catch (Exception ex) {
121+
throw new ClassConversionException((String)value, targetValueType, ex);
122+
}
123+
}
124+
else if (value instanceof Class) {
125+
clazz = (Class<?>)value;
126+
}
127+
else {
128+
clazz = value.getClass();
129+
}
130+
if (!targetValueType.isAssignableFrom(clazz)) {
131+
throw new ClassConversionException(clazz, targetValueType);
132+
}
133+
@SuppressWarnings("unchecked")
134+
Class<T> targetClass = (Class<T>) clazz;
135+
return targetClass;
122136
}
123-
else if (value instanceof Class) {
124-
clazz = (Class<?>)value;
125-
} else {
126-
clazz = value.getClass();
127-
}
128-
129-
if (!targetValueType.isAssignableFrom(clazz)) {
130-
throw new ClassConversionException(clazz, targetValueType);
131-
}
132-
@SuppressWarnings("unchecked")
133-
Class<T> targetClass = (Class<T>)clazz;
134-
return targetClass;
135137
}
136138
}
137-
138139
if (debugEnabled) {
139-
logger.debug(format("Could not find key '%s' in any property source. Returning [null]", key));
140+
logger.debug(String.format("Could not find key '%s' in any property source. Returning [null]", key));
140141
}
141142
return null;
142143
}
143144

145+
144146
@SuppressWarnings("serial")
145-
static class ClassConversionException extends ConversionException {
147+
private static class ClassConversionException extends ConversionException {
148+
146149
public ClassConversionException(Class<?> actual, Class<?> expected) {
147150
super(String.format("Actual type %s is not assignable to expected type %s", actual.getName(), expected.getName()));
148151
}
@@ -151,4 +154,5 @@ public ClassConversionException(String actual, Class<?> expected, Exception ex)
151154
super(String.format("Could not find/load class %s during attempt to convert to %s", actual, expected.getName()), ex);
152155
}
153156
}
157+
154158
}

spring-core/src/main/java/org/springframework/core/io/ResourceEditor.java

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,12 +19,11 @@
1919
import java.beans.PropertyEditorSupport;
2020
import java.io.IOException;
2121

22-
import org.springframework.core.env.StandardEnvironment;
2322
import org.springframework.core.env.PropertyResolver;
23+
import org.springframework.core.env.StandardEnvironment;
2424
import org.springframework.util.Assert;
2525
import org.springframework.util.StringUtils;
2626

27-
2827
/**
2928
* {@link java.beans.PropertyEditor Editor} for {@link Resource}
3029
* descriptors, to automatically convert {@code String} locations
@@ -51,7 +50,7 @@ public class ResourceEditor extends PropertyEditorSupport {
5150

5251
private final ResourceLoader resourceLoader;
5352

54-
private final PropertyResolver propertyResolver;
53+
private PropertyResolver propertyResolver;
5554

5655
private final boolean ignoreUnresolvablePlaceholders;
5756

@@ -61,7 +60,7 @@ public class ResourceEditor extends PropertyEditorSupport {
6160
* using a {@link DefaultResourceLoader} and {@link StandardEnvironment}.
6261
*/
6362
public ResourceEditor() {
64-
this(new DefaultResourceLoader(), new StandardEnvironment());
63+
this(new DefaultResourceLoader(), null);
6564
}
6665

6766
/**
@@ -73,17 +72,7 @@ public ResourceEditor() {
7372
*/
7473
@Deprecated
7574
public ResourceEditor(ResourceLoader resourceLoader) {
76-
this(resourceLoader, new StandardEnvironment(), true);
77-
}
78-
79-
/**
80-
* Create a new instance of the {@link ResourceEditor} class
81-
* using the given {@link ResourceLoader} and {@link PropertyResolver}.
82-
* @param resourceLoader the {@code ResourceLoader} to use
83-
* @param propertyResolver the {@code PropertyResolver} to use
84-
*/
85-
public ResourceEditor(ResourceLoader resourceLoader, PropertyResolver propertyResolver) {
86-
this(resourceLoader, propertyResolver, true);
75+
this(resourceLoader, null, true);
8776
}
8877

8978
/**
@@ -97,7 +86,17 @@ public ResourceEditor(ResourceLoader resourceLoader, PropertyResolver propertyRe
9786
*/
9887
@Deprecated
9988
public ResourceEditor(ResourceLoader resourceLoader, boolean ignoreUnresolvablePlaceholders) {
100-
this(resourceLoader, new StandardEnvironment(), ignoreUnresolvablePlaceholders);
89+
this(resourceLoader, null, ignoreUnresolvablePlaceholders);
90+
}
91+
92+
/**
93+
* Create a new instance of the {@link ResourceEditor} class
94+
* using the given {@link ResourceLoader} and {@link PropertyResolver}.
95+
* @param resourceLoader the {@code ResourceLoader} to use
96+
* @param propertyResolver the {@code PropertyResolver} to use
97+
*/
98+
public ResourceEditor(ResourceLoader resourceLoader, PropertyResolver propertyResolver) {
99+
this(resourceLoader, propertyResolver, true);
101100
}
102101

103102
/**
@@ -110,7 +109,6 @@ public ResourceEditor(ResourceLoader resourceLoader, boolean ignoreUnresolvableP
110109
*/
111110
public ResourceEditor(ResourceLoader resourceLoader, PropertyResolver propertyResolver, boolean ignoreUnresolvablePlaceholders) {
112111
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
113-
Assert.notNull(propertyResolver, "PropertyResolver must not be null");
114112
this.resourceLoader = resourceLoader;
115113
this.propertyResolver = propertyResolver;
116114
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
@@ -137,9 +135,11 @@ public void setAsText(String text) {
137135
* @see PropertyResolver#resolveRequiredPlaceholders
138136
*/
139137
protected String resolvePath(String path) {
140-
return this.ignoreUnresolvablePlaceholders ?
141-
this.propertyResolver.resolvePlaceholders(path) :
142-
this.propertyResolver.resolveRequiredPlaceholders(path);
138+
if (this.propertyResolver == null) {
139+
this.propertyResolver = new StandardEnvironment();
140+
}
141+
return (this.ignoreUnresolvablePlaceholders ? this.propertyResolver.resolvePlaceholders(path) :
142+
this.propertyResolver.resolveRequiredPlaceholders(path));
143143
}
144144

145145

0 commit comments

Comments
 (0)