In Java development, resource loading is a basic and important operation. This article will delve into two common resource loading methods in Java: the getResource method of ClassLoader and the getResource method of Class, and introduce the application of ResourceLoader in the Spring framework.
1. Two ways to load resources
1.1 ClassLoader’s getResource method
URL resourceFromClass = classLoader.getResource("demo.txt");
ClassLoader
The getResource
method is to ClassLoader
load the resource through an instance of the current class. Paths are relative to the classpath, allowing easy access to individual resources. It should be noted that the path should not start with "/", otherwise null may be returned.
1.2 Class getResource method
URL resourceFromClassWithPath = aClass.getResource("dir/demo.txt");
Class
The getResource
method loads resources through the current class, and the path is relative to the package where the current class is located. If the resource name starts with "/", the resource will be loaded using classpath as the base path. This method can easily obtain the resources in the current class package.
2. Obtain batch resources
Enumeration<URL> resources = classLoader.getResources("META-INF/MANIFEST.MF");
Through ClassLoader
the getResources
method, you can obtain all resources under the specified path and return an Enumeration
object. This is useful for scenarios where you need to handle multiple configuration files or metadata files.
3. Spring’s ResourceLoader and ResourcePatternResolver
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] springResources = resolver.getResources("classpath:/spring/*.xml");
The Spring framework provides ResourceLoader
and ResourcePatternResolver
interfaces, which encapsulate the resource loading method. In the above code, through PathMatchingResourcePatternResolver
examples, you can use wildcards to obtain all xml files under the classpath. This is very convenient for loading multiple configuration files.
4. Complete example
package com.lfsun.resources;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
public class MyResource {
public static void main(String[] args) throws Exception {
// 获取单个资源
// 获取当前类的Class对象
Class<MyResource> aClass = MyResource.class;
// 获取当前类的ClassLoader
ClassLoader classLoader = aClass.getClassLoader();
// 使用ClassLoader获取资源,路径相对于classpath
URL resourceFromClass = classLoader.getResource("demo.txt");
// 使用Class获取资源,路径相对于当前类所在的包
URL resourceFromClassWithPath = aClass.getResource("dir/demo.txt");
// 输出资源内容
if (resourceFromClass != null) {
byte[] bytes = readBytesFromStream(resourceFromClass.openStream());
System.out.println("ClassLoader获取的资源内容: " + new String(bytes));
}
if (resourceFromClassWithPath != null) {
byte[] bytes = readBytesFromStream(resourceFromClassWithPath.openStream());
System.out.println("Class获取的资源内容: " + new String(bytes));
}
// 获取批量资源
Enumeration<URL> resources = classLoader.getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
URL manifestResource = resources.nextElement();
System.out.println("Manifest资源: " + manifestResource);
}
// 使用Spring的ResourceLoader和ResourcePatternResolver
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// 使用通配符获取classpath下的所有xml文件
Resource[] springResources = resolver.getResources("classpath:/spring/*.xml");
// 输出Spring资源内容
for (Resource springResource : springResources) {
InputStream stream = springResource.getInputStream();
byte[] bytes = readBytesFromStream(stream);
System.out.println("Spring资源内容: " + new String(bytes));
}
}
private static byte[] readBytesFromStream(InputStream stream) throws IOException {
StringBuilder buffer = new StringBuilder();
byte[] bytes = new byte[1024];
int bytesRead;
while ((bytesRead = stream.read(bytes)) != -1) {
buffer.append(new String(bytes, 0, bytesRead));
}
return buffer.toString().getBytes();
}
}
Output:
D:\Config\java-17\bin\java.exe "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2023.2.4\lib\idea_rt.jar=62858:D:\Program Files\JetBrains\IntelliJ IDEA 2023.2.4\bin" -Dfile.encoding=UTF-8 -classpath D:\Users\Administrator\IdeaProjects\lfsun-study-java17\lfsun-study-resources\target\classes;D:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\3.2.1\spring-boot-starter-3.2.1.jar;D:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\3.2.1\spring-boot-3.2.1.jar;D:\Users\Administrator\.m2\repository\org\springframework\spring-context\6.1.2\spring-context-6.1.2.jar;D:\Users\Administrator\.m2\repository\org\springframework\spring-aop\6.1.2\spring-aop-6.1.2.jar;D:\Users\Administrator\.m2\repository\org\springframework\spring-beans\6.1.2\spring-beans-6.1.2.jar;D:\Users\Administrator\.m2\repository\org\springframework\spring-expression\6.1.2\spring-expression-6.1.2.jar;D:\Users\Administrator\.m2\repository\io\micrometer\micrometer-observation\1.12.1\micrometer-observation-1.12.1.jar;D:\Users\Administrator\.m2\repository\io\micrometer\micrometer-commons\1.12.1\micrometer-commons-1.12.1.jar;D:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\3.2.1\spring-boot-autoconfigure-3.2.1.jar;D:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\3.2.1\spring-boot-starter-logging-3.2.1.jar;D:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.4.14\logback-classic-1.4.14.jar;D:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.4.14\logback-core-1.4.14.jar;D:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.21.1\log4j-to-slf4j-2.21.1.jar;D:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-api\2.21.1\log4j-api-2.21.1.jar;D:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\2.0.9\jul-to-slf4j-2.0.9.jar;D:\Users\Administrator\.m2\repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar;D:\Users\Administrator\.m2\repository\org\springframework\spring-core\6.1.2\spring-core-6.1.2.jar;D:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\6.1.2\spring-jcl-6.1.2.jar;D:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\2.2\snakeyaml-2.2.jar;D:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\2.0.9\slf4j-api-2.0.9.jar com.lfsun.resources.MyResource
ClassLoader获取的资源内容: 这是 demo.txt 的内容。
Class获取的资源内容: 这是 dir/demo.txt 的内容。
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot-starter/3.2.1/spring-boot-starter-3.2.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot/3.2.1/spring-boot-3.2.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/spring-context/6.1.2/spring-context-6.1.2.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/spring-aop/6.1.2/spring-aop-6.1.2.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/spring-beans/6.1.2/spring-beans-6.1.2.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/spring-expression/6.1.2/spring-expression-6.1.2.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/io/micrometer/micrometer-observation/1.12.1/micrometer-observation-1.12.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/io/micrometer/micrometer-commons/1.12.1/micrometer-commons-1.12.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/3.2.1/spring-boot-autoconfigure-3.2.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/boot/spring-boot-starter-logging/3.2.1/spring-boot-starter-logging-3.2.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/ch/qos/logback/logback-classic/1.4.14/logback-classic-1.4.14.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/ch/qos/logback/logback-core/1.4.14/logback-core-1.4.14.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.21.1/log4j-to-slf4j-2.21.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/apache/logging/log4j/log4j-api/2.21.1/log4j-api-2.21.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/slf4j/jul-to-slf4j/2.0.9/jul-to-slf4j-2.0.9.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/spring-core/6.1.2/spring-core-6.1.2.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/springframework/spring-jcl/6.1.2/spring-jcl-6.1.2.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/yaml/snakeyaml/2.2/snakeyaml-2.2.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Users/Administrator/.m2/repository/org/slf4j/slf4j-api/2.0.9/slf4j-api-2.0.9.jar!/META-INF/MANIFEST.MF
Manifest资源: jar:file:/D:/Program%20Files/JetBrains/IntelliJ%20IDEA%202023.2.4/lib/idea_rt.jar!/META-INF/MANIFEST.MF
Spring资源内容: <!-- config1.xml -->
<beans>
<bean id="bean1" class="com.lfsun.resources.entity.Bean1"/>
</beans>
Spring资源内容: <!-- config2.xml -->
<beans>
<bean id="bean2" class="com.lfsun.resources.entity.Bean2"/>
</beans>
Process finished with exit code 0
Code structure:
The above output demonstrates the process of obtaining resource content through ClassLoader and Class, and loading multiple resources using Spring's ResourceLoader.