This article describes the various resource sources like file, class path, url etc. that spring abstracts out using a common interface Resource.
In the below example, we demonstrate how classPathResource picks up the the resource based on the classloader we pass.
Let's first build a jar which contains a file called "myResource.properties" in two different paths.
One of the myResource.properties is in the topmost directory and the second one is in sub-directory resources.
Spring Classpath Resource
ClassPath Resource
A class path resource like a class or a resource file is always identified with respect to a class loader.![]() |
Spring Classpath Resource |
In the below example, we demonstrate how classPathResource picks up the the resource based on the classloader we pass.
Let's first build a jar which contains a file called "myResource.properties" in two different paths.
One of the myResource.properties is in the topmost directory and the second one is in sub-directory resources.
Jar's directory structure
![]() |
Jar Command
jar cf test.jar myResource.properties resources/myResource.properties
Test case
Resource in classpath
Below is a simple test case to read the properties file from class path.public void testResourceLoadFromClasspath() throws IOException, URISyntaxException { Properties prop = new Properties(); prop.load(getClass().getResourceAsStream("myResource.properties")); assertEquals("classpath:myResource.properties", prop.get("path"));
}
Resource in jar file
Now we modify the test case to read the properties file from the jar.
public void testResourceLoadFromJar() throws IOException, URISyntaxException { URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{getClass().getResource("test.jar").toURI().toURL()}); ClassPathResource jarResource = new ClassPathResource("myResource.properties", classLoader); assertEquals("jar", jarResource.getURL().getProtocol());
Properties prop = new Properties();prop.load(jarResource.getInputStream()); assertEquals("jar:myResource.properties", prop.get("path")); }
Relative Resource in jar file
Next, we would like to read the second myResource.properties file which is in the sub-directory resources within the jar.
public void testRelativeResourceFromJar() throws IOException, URISyntaxException { URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{getClass().getResource("test.jar").toURI().toURL()}); ClassPathResource jarResource = new ClassPathResource("myResource.properties", classLoader);
Properties prop = new Properties();Resource relativeResource = jarResource.createRelative("resources/myResource.properties"); prop.load(relativeResource.getInputStream()); assertEquals("jar:resources/myResource.properties", prop.get("path")); }
Current thread context Classloader
If a classloader is not passed to the classPathResource, by default, first preference is given to the thread context classloader. If it is not set then the classloader of the current class is used. If we want some specific classloader to be used, we just need to set it to the current thread context. In the below test case, we set the jar's classloader as the thread context class loader.public void testDefaultClassLoader() throws IOException, URISyntaxException { try { Properties prop = new Properties(); URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{getClass().getResource("test.jar").toURI().toURL()}); Thread.currentThread().setContextClassLoader(classLoader); prop.load(new ClassPathResource("myResource.properties").getInputStream()); assertEquals("jar:myResource.properties", prop.get("path")); } finally { Thread.currentThread().setContextClassLoader(null); } }
Path name
Path name can have windows style '\\' or the inner simple dots like '..' or '.', the path is automatically normalized by spring.public void testDifferentPathNames() throws IOException, URISyntaxException { URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{getClass().getResource("test.jar").toURI().toURL()}); ClassPathResource jarResource = new ClassPathResource("resources/../resources/myResource.properties", classLoader); assertEquals("resources/myResource.properties", jarResource.getPath()); jarResource = new ClassPathResource("resources\\myResource.properties", classLoader); assertEquals("resources/myResource.properties", jarResource.getPath()); jarResource = new ClassPathResource("\\resources\\myResource.properties", classLoader); assertEquals("resources/myResource.properties", jarResource.getPath()); jarResource = new ClassPathResource("/resources/myResource.properties", classLoader); assertEquals("resources/myResource.properties", jarResource.getPath()); jarResource = new ClassPathResource("./resources/myResource.properties", classLoader); assertEquals("resources/myResource.properties", jarResource.getPath()); jarResource = new ClassPathResource("resources/../resources/./myResource.properties", classLoader); assertEquals("resources/myResource.properties", jarResource.getPath()); }
Home
No comments:
Post a Comment