16
16
17
17
package org .springframework .boot .io ;
18
18
19
+ import java .util .List ;
20
+
19
21
import org .springframework .core .io .ContextResource ;
20
22
import org .springframework .core .io .DefaultResourceLoader ;
21
23
import org .springframework .core .io .FileSystemResource ;
22
24
import org .springframework .core .io .ProtocolResolver ;
23
25
import org .springframework .core .io .Resource ;
26
+ import org .springframework .core .io .ResourceLoader ;
24
27
import org .springframework .core .io .support .SpringFactoriesLoader ;
28
+ import org .springframework .util .Assert ;
29
+ import org .springframework .util .StringUtils ;
25
30
26
31
/**
27
- * A {@link DefaultResourceLoader} with any {@link ProtocolResolver ProtocolResolvers}
28
- * registered in a {@code spring.factories} file applied to it. Plain paths without a
29
- * qualifier will resolve to file system resources. This is different from
32
+ * Class can be used to obtain {@link ResourceLoader ResourceLoaders} supporting
33
+ * additional {@link ProtocolResolver ProtocolResolvers} registered in
34
+ * {@code spring.factories}.
35
+ * <p>
36
+ * When not delegating to an existing resource loader, plain paths without a qualifier
37
+ * will resolve to file system resources. This is different from
30
38
* {@code DefaultResourceLoader}, which resolves unqualified paths to classpath resources.
31
39
*
32
40
* @author Scott Frederick
41
+ * @author Phillip Webb
33
42
* @since 3.3.0
34
43
*/
35
44
public class ApplicationResourceLoader extends DefaultResourceLoader {
36
45
37
46
/**
38
47
* Create a new {@code ApplicationResourceLoader}.
48
+ * @deprecated since 3.4.0 for removal in 3.6.0 in favor of {@link #get()}
39
49
*/
50
+ @ Deprecated (since = "3.4.0" , forRemoval = true )
40
51
public ApplicationResourceLoader () {
41
52
this (null );
42
53
}
@@ -46,7 +57,9 @@ public ApplicationResourceLoader() {
46
57
* @param classLoader the {@link ClassLoader} to load class path resources with, or
47
58
* {@code null} for using the thread context class loader at the time of actual
48
59
* resource access
60
+ * @deprecated since 3.4.0 for removal in 3.6.0 in favor of {@link #get(ClassLoader)}
49
61
*/
62
+ @ Deprecated (since = "3.4.0" , forRemoval = true )
50
63
public ApplicationResourceLoader (ClassLoader classLoader ) {
51
64
super (classLoader );
52
65
SpringFactoriesLoader loader = SpringFactoriesLoader .forDefaultResourceLocation (classLoader );
@@ -55,12 +68,107 @@ public ApplicationResourceLoader(ClassLoader classLoader) {
55
68
56
69
@ Override
57
70
protected Resource getResourceByPath (String path ) {
58
- return new FileSystemContextResource (path );
71
+ return new ApplicationResource (path );
72
+ }
73
+
74
+ /**
75
+ * Return a {@link ResourceLoader} supporting additional {@link ProtocolResolver
76
+ * ProtocolResolvers} registered in {@code spring.factories}. The factories file will
77
+ * be resolved using the default class loader at the time this call is made. Resources
78
+ * will be resolved using the default class loader at the time they are resolved.
79
+ * @return a {@link ResourceLoader} instance
80
+ * @since 3.4.0
81
+ */
82
+ public static ResourceLoader get () {
83
+ return get ((ClassLoader ) null );
84
+ }
85
+
86
+ /**
87
+ * Return a {@link ResourceLoader} supporting additional {@link ProtocolResolver
88
+ * ProtocolResolvers} registered in {@code spring.factories}. The factories files and
89
+ * resources will be resolved using the specified class loader.
90
+ * @param classLoader the class loader to use or {@code null} to use the default class
91
+ * loader
92
+ * @return a {@link ResourceLoader} instance
93
+ * @since 3.4.0
94
+ */
95
+ public static ResourceLoader get (ClassLoader classLoader ) {
96
+ return get (classLoader , SpringFactoriesLoader .forDefaultResourceLocation (classLoader ));
97
+ }
98
+
99
+ /**
100
+ * Return a {@link ResourceLoader} supporting additional {@link ProtocolResolver
101
+ * ProtocolResolvers} registered in {@code spring.factories}.
102
+ * @param classLoader the class loader to use or {@code null} to use the default class
103
+ * loader
104
+ * @param springFactoriesLoader the {@link SpringFactoriesLoader} used to load
105
+ * {@link ProtocolResolver ProtocolResolvers}
106
+ * @return a {@link ResourceLoader} instance
107
+ * @since 3.4.0
108
+ */
109
+ public static ResourceLoader get (ClassLoader classLoader , SpringFactoriesLoader springFactoriesLoader ) {
110
+ return get (ApplicationFileSystemResourceLoader .get (classLoader ), springFactoriesLoader );
59
111
}
60
112
61
- private static class FileSystemContextResource extends FileSystemResource implements ContextResource {
113
+ /**
114
+ * Return a {@link ResourceLoader} delegating to the given resource loader and
115
+ * supporting additional {@link ProtocolResolver ProtocolResolvers} registered in
116
+ * {@code spring.factories}. The factories file will be resolved using the default
117
+ * class loader at the time this call is made.
118
+ * @param resourceLoader the delegate resource loader
119
+ * @return a {@link ResourceLoader} instance
120
+ * @since 3.4.0
121
+ */
122
+ public static ResourceLoader get (ResourceLoader resourceLoader ) {
123
+ Assert .notNull (resourceLoader , "'resourceLoader' must not be null" );
124
+ return get (resourceLoader , SpringFactoriesLoader .forDefaultResourceLocation (resourceLoader .getClassLoader ()));
125
+ }
126
+
127
+ /**
128
+ * Return a {@link ResourceLoader} delegating to the given resource loader and
129
+ * supporting additional {@link ProtocolResolver ProtocolResolvers} registered in
130
+ * {@code spring.factories}.
131
+ * @param resourceLoader the delegate resource loader
132
+ * @param springFactoriesLoader the {@link SpringFactoriesLoader} used to load
133
+ * {@link ProtocolResolver ProtocolResolvers}
134
+ * @return a {@link ResourceLoader} instance
135
+ * @since 3.4.0
136
+ */
137
+ public static ResourceLoader get (ResourceLoader resourceLoader , SpringFactoriesLoader springFactoriesLoader ) {
138
+ Assert .notNull (resourceLoader , "'resourceLoader' must not be null" );
139
+ Assert .notNull (springFactoriesLoader , "'springFactoriesLoader' must not be null" );
140
+ return new ProtocolResolvingResourceLoader (resourceLoader , springFactoriesLoader .load (ProtocolResolver .class ));
141
+ }
142
+
143
+ /**
144
+ * Internal {@link ResourceLoader} used to load {@link ApplicationResource}.
145
+ */
146
+ private static final class ApplicationFileSystemResourceLoader extends DefaultResourceLoader {
147
+
148
+ private static final ResourceLoader shared = new ApplicationFileSystemResourceLoader (null );
149
+
150
+ private ApplicationFileSystemResourceLoader (ClassLoader classLoader ) {
151
+ super (classLoader );
152
+ }
62
153
63
- FileSystemContextResource (String path ) {
154
+ @ Override
155
+ protected Resource getResourceByPath (String path ) {
156
+ return new ApplicationResource (path );
157
+ }
158
+
159
+ static ResourceLoader get (ClassLoader classLoader ) {
160
+ return (classLoader != null ) ? new ApplicationFileSystemResourceLoader (classLoader )
161
+ : ApplicationFileSystemResourceLoader .shared ;
162
+ }
163
+
164
+ }
165
+
166
+ /**
167
+ * An application {@link Resource}.
168
+ */
169
+ private static final class ApplicationResource extends FileSystemResource implements ContextResource {
170
+
171
+ ApplicationResource (String path ) {
64
172
super (path );
65
173
}
66
174
@@ -71,4 +179,39 @@ public String getPathWithinContext() {
71
179
72
180
}
73
181
182
+ /**
183
+ * {@link ResourceLoader} decorator that adds support for additional
184
+ * {@link ProtocolResolver ProtocolResolvers}.
185
+ */
186
+ private static class ProtocolResolvingResourceLoader implements ResourceLoader {
187
+
188
+ private final ResourceLoader resourceLoader ;
189
+
190
+ private final List <ProtocolResolver > protocolResolvers ;
191
+
192
+ ProtocolResolvingResourceLoader (ResourceLoader resourceLoader , List <ProtocolResolver > protocolResolvers ) {
193
+ this .resourceLoader = resourceLoader ;
194
+ this .protocolResolvers = protocolResolvers ;
195
+ }
196
+
197
+ @ Override
198
+ public Resource getResource (String location ) {
199
+ if (StringUtils .hasLength (location )) {
200
+ for (ProtocolResolver protocolResolver : this .protocolResolvers ) {
201
+ Resource resource = protocolResolver .resolve (location , this );
202
+ if (resource != null ) {
203
+ return resource ;
204
+ }
205
+ }
206
+ }
207
+ return this .resourceLoader .getResource (location );
208
+ }
209
+
210
+ @ Override
211
+ public ClassLoader getClassLoader () {
212
+ return this .resourceLoader .getClassLoader ();
213
+ }
214
+
215
+ }
216
+
74
217
}
0 commit comments