diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index cb40597d748..b9661e23083 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -1035,8 +1035,8 @@ public class ServerProperties private boolean renameOnRotate; /** - * Set request attributes for IP address, Hostname, protocol and port used - * for the request. + * Set request attributes for IP address, Hostname, protocol and port used for + * the request. */ private boolean requestAttributesEnabled; diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ClassLoaderFilesResourcePatternResolver.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ClassLoaderFilesResourcePatternResolver.java index 2bbb7ebf309..51f24e31314 100644 --- a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ClassLoaderFilesResourcePatternResolver.java +++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ClassLoaderFilesResourcePatternResolver.java @@ -21,12 +21,8 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map.Entry; -import java.util.Set; import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile; import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind; @@ -48,9 +44,8 @@ import org.springframework.util.AntPathMatcher; */ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternResolver { - private static final Set LOCATION_PATTERN_PREFIXES = Collections - .unmodifiableSet(new HashSet( - Arrays.asList(CLASSPATH_ALL_URL_PREFIX, CLASSPATH_URL_PREFIX))); + private static final String[] LOCATION_PATTERN_PREFIXES = { CLASSPATH_ALL_URL_PREFIX, + CLASSPATH_URL_PREFIX }; private final ResourcePatternResolver delegate = new PathMatchingResourcePatternResolver(); @@ -63,17 +58,17 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe } @Override - public Resource getResource(String location) { - Resource candidate = this.delegate.getResource(location); - if (isExcludedResource(candidate)) { - return new DeletedClassLoaderFileResource(location); - } - return candidate; + public ClassLoader getClassLoader() { + return this.delegate.getClassLoader(); } @Override - public ClassLoader getClassLoader() { - return this.delegate.getClassLoader(); + public Resource getResource(String location) { + Resource candidate = this.delegate.getResource(location); + if (isDeleted(candidate)) { + return new DeletedClassLoaderFileResource(location); + } + return candidate; } @Override @@ -81,7 +76,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe List resources = new ArrayList(); Resource[] candidates = this.delegate.getResources(locationPattern); for (Resource candidate : candidates) { - if (!isExcludedResource(candidate)) { + if (!isDeleted(candidate)) { resources.add(candidate); } } @@ -89,38 +84,43 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe return resources.toArray(new Resource[resources.size()]); } - private String trimLocationPattern(String locationPattern) { - for (String prefix : LOCATION_PATTERN_PREFIXES) { - if (locationPattern.startsWith(prefix)) { - return locationPattern.substring(prefix.length()); - } - } - return locationPattern; - } - private List getAdditionalResources(String locationPattern) throws MalformedURLException { List additionalResources = new ArrayList(); String trimmedLocationPattern = trimLocationPattern(locationPattern); for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) { for (Entry entry : sourceFolder.getFilesEntrySet()) { - if (entry.getValue().getKind() == Kind.ADDED && this.antPathMatcher - .match(trimmedLocationPattern, entry.getKey())) { - additionalResources.add(new UrlResource(new URL("reloaded", null, -1, - "/" + entry.getKey(), - new ClassLoaderFileURLStreamHandler(entry.getValue())))); + String name = entry.getKey(); + ClassLoaderFile file = entry.getValue(); + if (file.getKind() == Kind.ADDED + && this.antPathMatcher.match(trimmedLocationPattern, name)) { + URL url = new URL("reloaded", null, -1, "/" + name, + new ClassLoaderFileURLStreamHandler(file)); + UrlResource resource = new UrlResource(url); + additionalResources.add(resource); } } } return additionalResources; } - private boolean isExcludedResource(Resource resource) { + private String trimLocationPattern(String pattern) { + for (String prefix : LOCATION_PATTERN_PREFIXES) { + if (pattern.startsWith(prefix)) { + return pattern.substring(prefix.length()); + } + } + return pattern; + } + + private boolean isDeleted(Resource resource) { for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) { for (Entry entry : sourceFolder.getFilesEntrySet()) { try { - if (entry.getValue().getKind() == Kind.DELETED && resource.exists() - && resource.getURI().toString().endsWith(entry.getKey())) { + String name = entry.getKey(); + ClassLoaderFile file = entry.getValue(); + if (file.getKind() == Kind.DELETED && resource.exists() + && resource.getURI().toString().endsWith(name)) { return true; } } @@ -136,8 +136,6 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe /** * A {@link Resource} that represents a {@link ClassLoaderFile} that has been * {@link Kind#DELETED deleted}. - * - * @author Andy Wilkinson */ private final class DeletedClassLoaderFileResource extends AbstractResource { @@ -161,5 +159,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe public InputStream getInputStream() throws IOException { throw new IOException(this.name + " has been deleted"); } + } + } diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java index abbfbd014ca..df548252b7a 100644 --- a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java +++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/Restarter.java @@ -421,8 +421,7 @@ public class Restarter { return; } if (applicationContext instanceof GenericApplicationContext) { - ((GenericApplicationContext) applicationContext).setResourceLoader( - new ClassLoaderFilesResourcePatternResolver(this.classLoaderFiles)); + prepare((GenericApplicationContext) applicationContext); } this.rootContexts.add(applicationContext); } @@ -433,6 +432,11 @@ public class Restarter { } } + private void prepare(GenericApplicationContext applicationContext) { + applicationContext.setResourceLoader( + new ClassLoaderFilesResourcePatternResolver(this.classLoaderFiles)); + } + private LeakSafeThread getLeakSafeThread() { try { return this.leakSafeThreads.takeFirst(); diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFileURLStreamHandler.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFileURLStreamHandler.java index cd4da3c642a..9ae99c8b550 100644 --- a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFileURLStreamHandler.java +++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/classloader/ClassLoaderFileURLStreamHandler.java @@ -27,6 +27,7 @@ import java.net.URLStreamHandler; * {@link URLStreamHandler} for the contents of a {@link ClassLoaderFile}. * * @author Phillip Webb + * @since 1.5.0 */ public class ClassLoaderFileURLStreamHandler extends URLStreamHandler { diff --git a/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/org/springframework/boot/devtools/tests/DevToolsIntegrationTests.java b/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/org/springframework/boot/devtools/tests/DevToolsIntegrationTests.java index 8c6ef0e9ed9..34ae3f8eb4c 100644 --- a/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/org/springframework/boot/devtools/tests/DevToolsIntegrationTests.java +++ b/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/org/springframework/boot/devtools/tests/DevToolsIntegrationTests.java @@ -146,8 +146,8 @@ public class DevToolsIntegrationTests { } Thread.sleep(100); } - int port = Integer - .valueOf(FileCopyUtils.copyToString(new FileReader(this.serverPortFile))); + FileReader portReader = new FileReader(this.serverPortFile); + int port = Integer.valueOf(FileCopyUtils.copyToString(portReader)); this.serverPortFile.delete(); return port; } @@ -187,5 +187,7 @@ public class DevToolsIntegrationTests { } builder.make().saveIn(this.classesDirectory); } + } + }