Improve performance of MessageSource condition
Update the MessageSourceAutoConfiguration condition to skip scanning for well known JARs. Results are now also cached. Fixes gh-1689
This commit is contained in:
parent
828efb2589
commit
001f2d6c69
|
|
@ -17,6 +17,8 @@
|
|||
package org.springframework.boot.autoconfigure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration.ResourceBundleCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
|
||||
|
|
@ -35,6 +37,7 @@ import org.springframework.core.annotation.Order;
|
|||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
|
||||
|
|
@ -44,6 +47,7 @@ import static org.springframework.util.StringUtils.trimAllWhitespace;
|
|||
* {@link EnableAutoConfiguration Auto-configuration} for {@link MessageSource}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnMissingBean(MessageSource.class)
|
||||
|
|
@ -99,11 +103,23 @@ public class MessageSourceAutoConfiguration {
|
|||
|
||||
protected static class ResourceBundleCondition extends SpringBootCondition {
|
||||
|
||||
private static ConcurrentReferenceHashMap<String, ConditionOutcome> cache = new ConcurrentReferenceHashMap<String, ConditionOutcome>();
|
||||
|
||||
@Override
|
||||
public ConditionOutcome getMatchOutcome(ConditionContext context,
|
||||
AnnotatedTypeMetadata metadata) {
|
||||
String basename = context.getEnvironment().getProperty(
|
||||
"spring.messages.basename", "messages");
|
||||
ConditionOutcome outcome = cache.get(basename);
|
||||
if (outcome == null) {
|
||||
outcome = getMatchOutcomeForBasename(context, basename);
|
||||
cache.put(basename, outcome);
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
|
||||
private ConditionOutcome getMatchOutcomeForBasename(ConditionContext context,
|
||||
String basename) {
|
||||
for (String name : commaDelimitedListToStringArray(trimAllWhitespace(basename))) {
|
||||
for (Resource resource : getResources(context.getClassLoader(), name)) {
|
||||
if (resource.exists()) {
|
||||
|
|
@ -118,7 +134,7 @@ public class MessageSourceAutoConfiguration {
|
|||
|
||||
private Resource[] getResources(ClassLoader classLoader, String name) {
|
||||
try {
|
||||
return new PathMatchingResourcePatternResolver(classLoader)
|
||||
return new SkipPatternPathMatchingResourcePatternResolver(classLoader)
|
||||
.getResources("classpath*:" + name + "*.properties");
|
||||
}
|
||||
catch (IOException ex) {
|
||||
|
|
@ -128,4 +144,60 @@ public class MessageSourceAutoConfiguration {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link PathMatchingResourcePatternResolver} that skips well known JARs that don't
|
||||
* contain messages.properties.
|
||||
*/
|
||||
private static class SkipPatternPathMatchingResourcePatternResolver extends
|
||||
PathMatchingResourcePatternResolver {
|
||||
|
||||
private static final ClassLoader ROOT_CLASSLOADER;
|
||||
static {
|
||||
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
|
||||
while (classLoader.getParent() != null) {
|
||||
classLoader = classLoader.getParent();
|
||||
}
|
||||
ROOT_CLASSLOADER = classLoader;
|
||||
}
|
||||
|
||||
private static final String[] SKIPPED = { "aspectjweaver-", "hibernate-core-",
|
||||
"hsqldb-", "jackson-annotations-", "jackson-core-", "jackson-databind-",
|
||||
"javassist-", "snakeyaml-", "spring-aop-", "spring-beans-",
|
||||
"spring-boot-", "spring-boot-actuator-", "spring-boot-autoconfigure-",
|
||||
"spring-core-", "spring-context-", "spring-data-commons-",
|
||||
"spring-expression-", "spring-jdbc-", "spring-orm-", "spring-tx-",
|
||||
"spring-web-", "spring-webmvc-", "tomcat-embed-", "joda-time-",
|
||||
"hibernate-entitymanager-", "hibernate-validator-", "logback-classic-",
|
||||
"logback-core-", "thymeleaf-" };
|
||||
|
||||
public SkipPatternPathMatchingResourcePatternResolver(ClassLoader classLoader) {
|
||||
super(classLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAllClassLoaderJarRoots(ClassLoader classLoader,
|
||||
Set<Resource> result) {
|
||||
if (classLoader != ROOT_CLASSLOADER) {
|
||||
super.addAllClassLoaderJarRoots(classLoader, result);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected Set<Resource> doFindAllClassPathResources(String path)
|
||||
throws IOException {
|
||||
Set<Resource> resources = super.doFindAllClassPathResources(path);
|
||||
for (Iterator<Resource> iterator = resources.iterator(); iterator.hasNext();) {
|
||||
Resource resource = iterator.next();
|
||||
for (String skipped : SKIPPED) {
|
||||
if (resource.getFilename().startsWith(skipped)) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue