I'm trying to intercept certain URL patterns to resolve into the correct UrlResource, but the application context does not honour custom protocol resolvers.

In pseudocode:

GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.setResourceLoader(someResourceLoader);
applicationContext.addProtocolResolver(new CustomUrlResolver());
applicationContext.getResource("http://some.custom.url/"); // never resolved via CustomUrlResolver

The CustomUrlResolver resolver is never invoked because someResourceLoader takes precedence in getResource. Unfortunately, there's no way to work around this issue by adding a delegating resource loader, since there's no accessor for the resource loader.

I believe that the setResourceLoader(...) call is done somewhere in Spring Boot.

I had to do setResourceLoader(null). This is likely going to break things.

Comment From: sbrannen

Thanks for bringing this to our attention.

At a glance, it appears that a solution might be as simple as the following in GenericApplicationContext (i.e., copying the for-loop from the superclass -- although the for-loop would get executed twice in some cases).

public Resource getResource(String location) {
    for (ProtocolResolver protocolResolver : getProtocolResolvers()) {
        Resource resource = protocolResolver.resolve(location, this);
        if (resource != null) {
            return resource;
        }
    }
    if (this.resourceLoader != null) {
        return this.resourceLoader.getResource(location);
    }
    return super.getResource(location);
}

We'll look into it.

Comment From: arteymix

In that case, you can put the for-loop within the this.resourceLoader != null condition.

Comment From: sbrannen

In that case, you can put the for-loop within the this.resourceLoader != null condition.

Yes. You are of course correct, and that's exactly how I implemented it. 👍

When I said "at a glance", I meant that literally. It was the last thing I glanced at before signing off for the day, and I hadn't even put any thought into how to optimize the code. 😇

This is in place now for 5.3.22 (available soon in snapshots).