In-depth understanding of resource loading methods in Java and Spring's ResourceLoader application

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");

ClassLoaderThe getResourcemethod is to ClassLoaderload 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");

ClassThe getResourcemethod 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 ClassLoaderthe getResourcesmethod, you can obtain all resources under the specified path and return an Enumerationobject. 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 ResourceLoaderand ResourcePatternResolverinterfaces, which encapsulate the resource loading method. In the above code, through PathMatchingResourcePatternResolverexamples, 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:

image.png

The above output demonstrates the process of obtaining resource content through ClassLoader and Class, and loading multiple resources using Spring's ResourceLoader.

Guess you like

Origin blog.csdn.net/qq_43116031/article/details/135418644