Merge branch '1.5.x'

pull/8026/head
Andy Wilkinson 8 years ago
commit 4548af2966

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.boot.devtools.restart;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
@ -40,6 +41,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.PathMatcher; import org.springframework.util.PathMatcher;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.ServletContextResource; import org.springframework.web.context.support.ServletContextResource;
import org.springframework.web.context.support.ServletContextResourcePatternResolver; import org.springframework.web.context.support.ServletContextResourcePatternResolver;
@ -59,7 +61,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
private static final String WEB_CONTEXT_CLASS = "org.springframework.web.context." private static final String WEB_CONTEXT_CLASS = "org.springframework.web.context."
+ "WebApplicationContext"; + "WebApplicationContext";
private final ResourcePatternResolver delegate; private final ResourcePatternResolver patternResolverDelegate;
private final PathMatcher antPathMatcher = new AntPathMatcher(); private final PathMatcher antPathMatcher = new AntPathMatcher();
@ -68,8 +70,19 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
ClassLoaderFilesResourcePatternResolver(ApplicationContext applicationContext, ClassLoaderFilesResourcePatternResolver(ApplicationContext applicationContext,
ClassLoaderFiles classLoaderFiles) { ClassLoaderFiles classLoaderFiles) {
this.classLoaderFiles = classLoaderFiles; this.classLoaderFiles = classLoaderFiles;
this.delegate = getResourcePatternResolverFactory() this.patternResolverDelegate = getResourcePatternResolverFactory()
.getResourcePatternResolver(applicationContext); .getResourcePatternResolver(applicationContext,
retrieveResourceLoader(applicationContext));
}
private ResourceLoader retrieveResourceLoader(ApplicationContext applicationContext) {
Field field = ReflectionUtils.findField(applicationContext.getClass(),
"resourceLoader", ResourceLoader.class);
if (field == null) {
return null;
}
ReflectionUtils.makeAccessible(field);
return (ResourceLoader) ReflectionUtils.getField(field, applicationContext);
} }
private ResourcePatternResolverFactory getResourcePatternResolverFactory() { private ResourcePatternResolverFactory getResourcePatternResolverFactory() {
@ -81,12 +94,12 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
@Override @Override
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
return this.delegate.getClassLoader(); return this.patternResolverDelegate.getClassLoader();
} }
@Override @Override
public Resource getResource(String location) { public Resource getResource(String location) {
Resource candidate = this.delegate.getResource(location); Resource candidate = this.patternResolverDelegate.getResource(location);
if (isDeleted(candidate)) { if (isDeleted(candidate)) {
return new DeletedClassLoaderFileResource(location); return new DeletedClassLoaderFileResource(location);
} }
@ -96,7 +109,8 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
@Override @Override
public Resource[] getResources(String locationPattern) throws IOException { public Resource[] getResources(String locationPattern) throws IOException {
List<Resource> resources = new ArrayList<Resource>(); List<Resource> resources = new ArrayList<Resource>();
Resource[] candidates = this.delegate.getResources(locationPattern); Resource[] candidates = this.patternResolverDelegate
.getResources(locationPattern);
for (Resource candidate : candidates) { for (Resource candidate : candidates) {
if (!isDeleted(candidate)) { if (!isDeleted(candidate)) {
resources.add(candidate); resources.add(candidate);
@ -190,8 +204,9 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
private static class ResourcePatternResolverFactory { private static class ResourcePatternResolverFactory {
public ResourcePatternResolver getResourcePatternResolver( public ResourcePatternResolver getResourcePatternResolver(
ApplicationContext applicationContext) { ApplicationContext applicationContext, ResourceLoader resourceLoader) {
return new PathMatchingResourcePatternResolver(); return new PathMatchingResourcePatternResolver(resourceLoader == null
? new DefaultResourceLoader() : resourceLoader);
} }
} }
@ -205,13 +220,14 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
@Override @Override
public ResourcePatternResolver getResourcePatternResolver( public ResourcePatternResolver getResourcePatternResolver(
ApplicationContext applicationContext) { ApplicationContext applicationContext, ResourceLoader resourceLoader) {
if (applicationContext instanceof WebApplicationContext) { if (applicationContext instanceof WebApplicationContext) {
return new ServletContextResourcePatternResolver( return new ServletContextResourcePatternResolver(resourceLoader == null
new WebApplicationContextResourceLoader( ? new WebApplicationContextResourceLoader(
(WebApplicationContext) applicationContext)); (WebApplicationContext) applicationContext)
: resourceLoader);
} }
return super.getResourcePatternResolver(applicationContext); return super.getResourcePatternResolver(applicationContext, resourceLoader);
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -31,17 +31,21 @@ import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles;
import org.springframework.context.support.GenericApplicationContext; import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.mock.web.MockServletContext; import org.springframework.mock.web.MockServletContext;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.context.support.ServletContextResource; import org.springframework.web.context.support.ServletContextResource;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/** /**
* Tests for {@link ClassLoaderFilesResourcePatternResolver}. * Tests for {@link ClassLoaderFilesResourcePatternResolver}.
* *
* @author Phillip Webb * @author Phillip Webb
* @author Andy Wilkinson
*/ */
public class ClassLoaderFilesResourcePatternResolverTests { public class ClassLoaderFilesResourcePatternResolverTests {
@ -111,6 +115,27 @@ public class ClassLoaderFilesResourcePatternResolverTests {
assertThat(resources).isEmpty(); assertThat(resources).isEmpty();
} }
@Test
public void customResourceLoaderIsUsedInNonWebApplication() throws Exception {
GenericApplicationContext context = new GenericApplicationContext();
ResourceLoader resourceLoader = mock(ResourceLoader.class);
context.setResourceLoader(resourceLoader);
this.resolver = new ClassLoaderFilesResourcePatternResolver(context, this.files);
this.resolver.getResource("foo.txt");
verify(resourceLoader).getResource("foo.txt");
}
@Test
public void customResourceLoaderIsUsedInWebApplication() throws Exception {
GenericWebApplicationContext context = new GenericWebApplicationContext(
new MockServletContext());
ResourceLoader resourceLoader = mock(ResourceLoader.class);
context.setResourceLoader(resourceLoader);
this.resolver = new ClassLoaderFilesResourcePatternResolver(context, this.files);
this.resolver.getResource("foo.txt");
verify(resourceLoader).getResource("foo.txt");
}
private File createFile(File folder, String name) throws IOException { private File createFile(File folder, String name) throws IOException {
File file = new File(folder, name); File file = new File(folder, name);
FileCopyUtils.copy("test".getBytes(), file); FileCopyUtils.copy("test".getBytes(), file);

Loading…
Cancel
Save