If the bean will independently determine and provide the path to resources through some dynamic process, it probably makes sense to use the ResourceLoader or ResourcePatternResolver interface to load resources. For example, consider loading a template where the specific resource needed depends on the user's role. If the resources are static, then it makes sense to completely abandon the use of the ResourceLoader interface (or the ResourcePatternResolver interface), let the bean expose the Resource properties that it needs, and expects them to be embedded in it.

What makes it trivial to subsequently implement these properties is that all application contexts register and use a special PropertyEditor JavaBeans class that can convert String paths to objects Resource. For example, the following class MyBean has a property template of type Resource.

Java
package example;
public class MyBean {
    private Resource template;
    public setTemplate(Resource template) {
        this.template = template;
    }
    // ...
}
Kotlin
class MyBean(var template: Resource)

In an XML configuration file, the template property can be configured with a simple string for a given resource, as shown in the following example:

<bean id="myBean" class="example.MyBean">
    <property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>

Note that the resource path does not have a prefix. Therefore, since the application context itself will be used as a ResourceLoader, the resource is loaded via ClassPathResource, FileSystemResource or ServletContextResource depending on the exact type of application context.

If you need to force the use of a specific Resource type, you can use a prefix. The following two examples show how to force the use of ClassPathResource and UrlResource (the latter is used to access a file on the file system):

<property name="template" value="classpath:some/resource/path/myTemplate.txt">
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>

If the MyBean class is refactored (redesigned) for use with annotation-driven configuration, the path to myTemplate.txt can be stored in a key named template.path - for example, in the properties file available for Environment in Spring. The template path can then be referenced with the @Value annotation using the property placeholder. Spring will receive the template path value as a string, and a special PropertyEditor will convert the string into a Resource object, which will be injected into the MyBean constructor. The following example shows how to achieve this.

Java
@Component
public class MyBean {
    private final Resource template;
    public MyBean(@Value("${template.path}") Resource template) {
        this.template = template;
    }
    // ...
}
Kotlin
@Component
class MyBean(@Value("\${template.path}") private val template: Resource)

If we want to support multiple templates found in the same path in multiple places on the classpath - for example, in multiple jars on the classpath - we can use a special prefix classpath*: and wildcards to define the templates.path key as classpath*:/config/templates/*.txt. If we override the MyBean class as follows, Spring converts the template path template into an array of Resource objects that can be injected into the MyBean constructor.

Java
@Component
public class MyBean {
    private final Resource[] templates;
    public MyBean(@Value("${templates.path}") Resource[] templates) {
        this.templates = templates;
    }
    // ...
}
Kotlin
@Component
class MyBean(@Value("\${templates.path}") private val templates: Resource[])