Open In App

Spring – ResourceLoaderAware with Example

Prerequisite: Introduction to Spring Framework

In this article, we will discuss the various ways through which we can load resources or files (e.g. text files, XML files, properties files, etc.) into the Spring application context. These resources or files may be present at different locations like in the file system, classpath, or URL. Spring provides the Resource and ResourceLoader interfaces. The Resource interface represents external resources and the ResourceLoader interface provides a unified method i.e. getResource() to retrieve an external resource represented by a resource object.






public interface Resource extends InputStreamSource {
    boolean exists();
    boolean isOpen();
    URL getURL() throws IOException;
    File getFile() throws IOException;
    Resource createRelative(String relativePath) throws IOException;
    String getFilename();
    String getDescription();
}
  
public interface InputStreamSource {
    InputStream getInputStream() throws IOException;
}




public interface ResourceLoader {
    Resource getResource(String location);
}

As we discussed earlier, the Resource interface represents an external resource. As we know, we can’t create an object of the interface. Spring provides the following 6 implementations for the Resource interface.

There are a few ways through which we can read/load external files via. creation of Resource object.



1. Through the ApplicationContext Interface




public interface ResourceLoader {
    Resource getResource(String location);
}

The ResourceLoader interface is meant to be implemented by objects that can return (i.e. load) Resource instances. In Spring, all application contexts implement the ResourceLoader interface. Therefore, all application contexts may be used to obtain Resource instances. Let’s see how we can load/read external resources/files by using application context :




package com.gfg.technicalscripter;
  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
  
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
  
public class App {
    public static void main(String[] args)
    {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext();
  
        // Through File system
        Resource fileResource = applicationContext.getResource("file:c:\\gfg-testing.txt");
  
        // Through URL path
        Resource urlResource = applicationContext.getResource("url:http:// www.gfg.com/gfg-testing.txt");
  
        // Through Classpath
        Resource classpathResource = applicationContext
                                         .getResource("classpath:com/gfg/technicalscripter/gfg-testing.txt");
  
        readFileThroughResource(classpathResource);
        // We can call readFileThroughResource for
        // any resource object representing a file
    }
  
    private static void readFileThroughResource(Resource resource)
    {
        try {
            InputStream is = resource.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
  
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            br.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Spring project structure & gfg-testing.txt file content:

 

 

Screenshot of output console:

 

2. Through the ResourceLoaderAware interface

Since spring bean does not have access to the spring application context, So how can a bean load/access resources or files (e.g. text files, XML files, properties files, etc.)? To solve this issue, the workaround is to implement the ResourceLoaderAware interface and create a setter method for the ResourceLoader object. At last, spring will inject the resource loader into your bean.




package com.gfg.technicalscripter;
  
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
  
public class CustomResourceLoader implements ResourceLoaderAware {
  
    private ResourceLoader resourceLoader;
  
    public void setResourceLoader(ResourceLoader resourceLoader)
    {
        this.resourceLoader = resourceLoader;
    }
  
    public Resource getResource(String location)
    {
        return resourceLoader.getResource(location);
    }
}




    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  
    <bean id="customResourceLoader" class="com.gfg.technicalscripter.CustomResourceLoader" />
  
</beans>




package com.gfg.technicalscripter;
  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
  
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
  
public class App {
    public static void main(String[] args)
    {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:com/gfg/technicalscripter/config.xml");
        CustomResourceLoader customResourceLoader = applicationContext.getBean(CustomResourceLoader.class);
        Resource classpathResource = customResourceLoader
                                         .getResource("classpath:com/gfg/technicalscripter/gfg-testing.txt");
  
        readFileThroughResource(classpathResource);
    }
  
    private static void readFileThroughResource(Resource resource)
    {
        try {
            InputStream is = resource.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
  
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            br.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Screenshot of output console:

 

When a class implements ResourceLoaderAware and is deployed into an application context (as a Spring-managed bean), it is recognized as ResourceLoaderAware by the application context. The application context will then invoke the setResourceLoader(ResourceLoader), supplying itself as the argument (remember, all application contexts in Spring implement the ResourceLoader interface). This getResource() method is very helpful to deal with different resources with different solutions, like File object for file system resource, and URL object for URL resource and it really saves a lot of time.


Article Tags :