Skip to content

Introduce getResources() method in ResourceLoader interface #26443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nightswimmings opened this issue Jan 26, 2021 · 4 comments
Closed

Introduce getResources() method in ResourceLoader interface #26443

nightswimmings opened this issue Jan 26, 2021 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@nightswimmings
Copy link

nightswimmings commented Jan 26, 2021

I would like to suggest as new feature the possibility to add a getResources() method to the ResourceLoader interface, and if it accepted wildcards it would be even nicer. I assume there must be a rationale to prevent this, but just in case.

I don't understand why the out-of-the-box auto-configured ResourceLoader implementation is not prepared for these needs.

It seems to me, from my ignorance, that 90% of the apps would benefit from having a single central ResourceLoader that deals with all kinds of resources.

Currently I cannot have an @Autowired ResourceLoader, not even override it because I have to manually deal with concrete implementation PathMatchingResourcePatternResolver.

Thanks mates!

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 26, 2021
@sbrannen sbrannen added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Jan 26, 2021
@sbrannen sbrannen changed the title Feature suggestion: Enrich ResourceLoader interface Introduce getResources() method in ResourceLoader interface Jan 26, 2021
@sbrannen sbrannen self-assigned this Jan 26, 2021
@sbrannen sbrannen added status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 26, 2021
@sbrannen
Copy link
Member

I would like to suggest as new feature the possibility to add a getResources() method to the ResourceLoader interface, and if it accepted wildcards it would be even nicer.

The ResourcePatternResolver interface -- which extends the ResourceLoader interface -- already defines the proposed Resource[] getResources(String locationPattern) method.

I don't understand why the out-of-the-box auto-configured ResourceLoader implementation is not prepared for these needs.

The default ResourceLoader in any standard ApplicationContext is in fact an instance of PathMatchingResourcePatternResolver which implements the ResourcePatternResolver interface.

The same is true for the ApplicationContext instance itself which also implements the ResourcePatternResolver interface (and delegates to the default PathMatchingResourcePatternResolver).

From the class-level Javadoc for ResourceLoaderAware:

A passed-in ResourceLoader can also be checked for the org.springframework.core.io.support.ResourcePatternResolver interface and cast accordingly, in order to resolve resource patterns into arrays of Resource objects. This will always work when running in an ApplicationContext (since the context interface extends the ResourcePatternResolver interface). Use a org.springframework.core.io.support.PathMatchingResourcePatternResolver as default; see also the ResourcePatternUtils.getResourcePatternResolver method.

As an alternative to a ResourcePatternResolver dependency, consider exposing bean properties of type Resource[] array, populated via pattern Strings with automatic type conversion by the bean factory at binding time.


Currently I cannot have an @Autowired ResourceLoader, not even override it because I have to manually deal with concrete implementation PathMatchingResourcePatternResolver.

As mentioned above (in the Javadoc for ResourceLoaderAware), as an alternative to a ResourcePatternResolver dependency, consider exposing bean properties of type Resource[] array, populated via pattern Strings with automatic type conversion by the bean factory at binding time.

That suggestion is focused on XML bean configuration, but the same applies to annotation driven configuration via @Value and @Autowired.

With regard to your claim that you cannot autowire a ResouceLoader, I put together the following example to demonstrate that Spring provides support for autowiring an ApplicationContext, ResourceLoader, or ResourcePatternResolver for looking up resources within your components.

@SpringJUnitConfig
class ResourceLoaderTests {

	@Autowired
	ApplicationContext context;

	@Autowired
	ResourceLoader resourceLoader;

	@Autowired
	ResourcePatternResolver resourcePatternResolver;

	@Test
	void test() throws Exception {
		assertThat(context.getResource("classpath:/org/springframework/test/context/jdbc/schema.sql").exists()).isTrue();
		assertThat(resourceLoader.getResource("classpath:/org/springframework/test/context/jdbc/schema.sql").exists()).isTrue();
		assertThat(context.getResources("classpath*:/org/springframework/test/context/jdbc/*.sql")).hasSize(9);
		assertThat(resourcePatternResolver.getResources("classpath*:/org/springframework/test/context/jdbc/*.sql")).hasSize(9);
	}

	@Configuration
	static class Config {
	}
}

The above test class resides locally in my copy of the spring-test module for which 9 SQL scripts exist in the /org/springframework/test/context/jdbc folder in src/test/resources.

In light of the above, I am closing this issue.

@nightswimmings
Copy link
Author

nightswimmings commented Jan 26, 2021

@sbrannen I am really sorry, for wasting your time, and I really appreciate your dedication in answer me.
I misunderstood the documentation because what I am really striving for is ResourcePatternResolver as you said, which in my view, should be the reference central bean (I personally don't see the point of ResourceLoader interface which is the reference component in https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#resources, as a convention). When I said I cannot override ResourceLoader I meant using the PathMatchingResourcePatternResolver implementation as the custom one for ResourceLoader, because that interface did not expose the patchMatchinfg methods, but as you said, it was a misunderstanding because what I really want is ResourcePatternResolver subinterface instead of ResourceLoader, even more if as I already figure it out, is by common sense the default and most useful implementation and the provided one it seems.
Perhaps dedicating the actual ResourceLoader section (because of possibilities and relevance) in Spring Docs to the ResourcePatternResolver, would be much more useful for the average reader

@sbrannen
Copy link
Member

Perhaps dedicating the actual ResourceLoader section (because of possibilities and relevance) in Spring Docs to the ResourcePatternResolver, would be much more useful for the average reader

That's a good point. Thanks for mentioning that about the reference docs. I agree that it would be beneficial to discuss ResourcePatternResolver as a first-class option alongside ResourceLoader, and I have created #26447 to address this and other shortcomings in that section of the reference docs.

@nightswimmings
Copy link
Author

You are amazing guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants