commit
81ddebbc27
|
|
@ -22,8 +22,10 @@ import java.lang.reflect.Field;
|
|||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
|
||||
|
|
@ -31,6 +33,7 @@ import org.springframework.boot.devtools.restart.classloader.ClassLoaderFileURLS
|
|||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceFolder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.core.io.AbstractResource;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.ProtocolResolver;
|
||||
|
|
@ -67,7 +70,8 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
|
|||
|
||||
private final ClassLoaderFiles classLoaderFiles;
|
||||
|
||||
ClassLoaderFilesResourcePatternResolver(ApplicationContext applicationContext, ClassLoaderFiles classLoaderFiles) {
|
||||
ClassLoaderFilesResourcePatternResolver(AbstractApplicationContext applicationContext,
|
||||
ClassLoaderFiles classLoaderFiles) {
|
||||
this.classLoaderFiles = classLoaderFiles;
|
||||
this.patternResolverDelegate = getResourcePatternResolverFactory()
|
||||
.getResourcePatternResolver(applicationContext, retrieveResourceLoader(applicationContext));
|
||||
|
|
@ -195,28 +199,11 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
|
|||
*/
|
||||
private static class ResourcePatternResolverFactory {
|
||||
|
||||
ResourcePatternResolver getResourcePatternResolver(ApplicationContext applicationContext,
|
||||
ResourcePatternResolver getResourcePatternResolver(AbstractApplicationContext applicationContext,
|
||||
ResourceLoader resourceLoader) {
|
||||
if (resourceLoader == null) {
|
||||
resourceLoader = new DefaultResourceLoader();
|
||||
copyProtocolResolvers(applicationContext, resourceLoader);
|
||||
}
|
||||
return new PathMatchingResourcePatternResolver(resourceLoader);
|
||||
}
|
||||
|
||||
protected final void copyProtocolResolvers(ApplicationContext applicationContext,
|
||||
ResourceLoader resourceLoader) {
|
||||
if (applicationContext instanceof DefaultResourceLoader
|
||||
&& resourceLoader instanceof DefaultResourceLoader) {
|
||||
copyProtocolResolvers((DefaultResourceLoader) applicationContext,
|
||||
(DefaultResourceLoader) resourceLoader);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void copyProtocolResolvers(DefaultResourceLoader source, DefaultResourceLoader destination) {
|
||||
for (ProtocolResolver resolver : source.getProtocolResolvers()) {
|
||||
destination.addProtocolResolver(resolver);
|
||||
}
|
||||
ResourceLoader targetResourceLoader = (resourceLoader != null) ? resourceLoader
|
||||
: new ApplicationContextResourceLoader(applicationContext::getProtocolResolvers);
|
||||
return new PathMatchingResourcePatternResolver(targetResourceLoader);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -228,21 +215,35 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
|
|||
private static class WebResourcePatternResolverFactory extends ResourcePatternResolverFactory {
|
||||
|
||||
@Override
|
||||
public ResourcePatternResolver getResourcePatternResolver(ApplicationContext applicationContext,
|
||||
public ResourcePatternResolver getResourcePatternResolver(AbstractApplicationContext applicationContext,
|
||||
ResourceLoader resourceLoader) {
|
||||
if (applicationContext instanceof WebApplicationContext) {
|
||||
return getResourcePatternResolver((WebApplicationContext) applicationContext, resourceLoader);
|
||||
return getServletContextResourcePatternResolver(applicationContext, resourceLoader);
|
||||
}
|
||||
return super.getResourcePatternResolver(applicationContext, resourceLoader);
|
||||
}
|
||||
|
||||
private ResourcePatternResolver getResourcePatternResolver(WebApplicationContext applicationContext,
|
||||
ResourceLoader resourceLoader) {
|
||||
if (resourceLoader == null) {
|
||||
resourceLoader = new WebApplicationContextResourceLoader(applicationContext);
|
||||
copyProtocolResolvers(applicationContext, resourceLoader);
|
||||
}
|
||||
return new ServletContextResourcePatternResolver(resourceLoader);
|
||||
private ResourcePatternResolver getServletContextResourcePatternResolver(
|
||||
AbstractApplicationContext applicationContext, ResourceLoader resourceLoader) {
|
||||
ResourceLoader targetResourceLoader = (resourceLoader != null) ? resourceLoader
|
||||
: new WebApplicationContextResourceLoader(applicationContext::getProtocolResolvers,
|
||||
(WebApplicationContext) applicationContext);
|
||||
return new ServletContextResourcePatternResolver(targetResourceLoader);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ApplicationContextResourceLoader extends DefaultResourceLoader {
|
||||
|
||||
private final Supplier<Collection<ProtocolResolver>> protocolResolvers;
|
||||
|
||||
ApplicationContextResourceLoader(Supplier<Collection<ProtocolResolver>> protocolResolvers) {
|
||||
this.protocolResolvers = protocolResolvers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProtocolResolver> getProtocolResolvers() {
|
||||
return this.protocolResolvers.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -251,11 +252,13 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
|
|||
* {@link ResourceLoader} that optionally supports {@link ServletContextResource
|
||||
* ServletContextResources}.
|
||||
*/
|
||||
private static class WebApplicationContextResourceLoader extends DefaultResourceLoader {
|
||||
private static class WebApplicationContextResourceLoader extends ApplicationContextResourceLoader {
|
||||
|
||||
private final WebApplicationContext applicationContext;
|
||||
|
||||
WebApplicationContextResourceLoader(WebApplicationContext applicationContext) {
|
||||
WebApplicationContextResourceLoader(Supplier<Collection<ProtocolResolver>> protocolResolvers,
|
||||
WebApplicationContext applicationContext) {
|
||||
super(protocolResolvers);
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,18 @@ class ClassLoaderFilesResourcePatternResolverTests {
|
|||
verify(resolver).resolve(eq("foo:some-file.txt"), any(ResourceLoader.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customProtocolResolverRegisteredAfterCreationIsUsedInNonWebApplication() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
Resource resource = mock(Resource.class);
|
||||
this.resolver = new ClassLoaderFilesResourcePatternResolver(context, this.files);
|
||||
ProtocolResolver resolver = mockProtocolResolver("foo:some-file.txt", resource);
|
||||
context.addProtocolResolver(resolver);
|
||||
Resource actual = this.resolver.getResource("foo:some-file.txt");
|
||||
assertThat(actual).isSameAs(resource);
|
||||
verify(resolver).resolve(eq("foo:some-file.txt"), any(ResourceLoader.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customResourceLoaderIsUsedInWebApplication() {
|
||||
GenericWebApplicationContext context = new GenericWebApplicationContext(new MockServletContext());
|
||||
|
|
@ -149,6 +161,18 @@ class ClassLoaderFilesResourcePatternResolverTests {
|
|||
verify(resolver).resolve(eq("foo:some-file.txt"), any(ResourceLoader.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customProtocolResolverRegisteredAfterCreationIsUsedInWebApplication() {
|
||||
GenericWebApplicationContext context = new GenericWebApplicationContext(new MockServletContext());
|
||||
Resource resource = mock(Resource.class);
|
||||
this.resolver = new ClassLoaderFilesResourcePatternResolver(context, this.files);
|
||||
ProtocolResolver resolver = mockProtocolResolver("foo:some-file.txt", resource);
|
||||
context.addProtocolResolver(resolver);
|
||||
Resource actual = this.resolver.getResource("foo:some-file.txt");
|
||||
assertThat(actual).isSameAs(resource);
|
||||
verify(resolver).resolve(eq("foo:some-file.txt"), any(ResourceLoader.class));
|
||||
}
|
||||
|
||||
private ProtocolResolver mockProtocolResolver(String path, Resource resource) {
|
||||
ProtocolResolver resolver = mock(ProtocolResolver.class);
|
||||
given(resolver.resolve(eq(path), any(ResourceLoader.class))).willReturn(resource);
|
||||
|
|
|
|||
Loading…
Reference in New Issue