I am not sure this is more suited for Spring-Boot or Spring Core, but I think it would be beneficial to allow resources to be defined as plain strings.

The idea of Resource is abstracting a resource, whether it comes from a file, an url, etc.. so why not plain text? That way we allow the user passing a file with "foobar" but also the content itself, which would be impossible now

Perhaps something like my-resource-binded-property: "raw:file_content" (where "raw" could be a keyword prefix like "classpath:", or "bare:" or "string:")

Comment From: wilkinsona

Thanks for the suggestion, @nightswimmings. You can achieve this today without too much code by plugging in your own ProtocolResolver. Here's an example that shows a configuration properties bound Resource that's configured using a string with a custom prefix:

package com.example.demo;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ProtocolResolver;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.StreamUtils;

@SpringBootApplication
@ConfigurationProperties("example")
public class Gh28714Application {

    private Resource resource;

    public Resource getResource() {
        return resource;
    }

    public void setResource(Resource resource) {
        this.resource = resource;
    }

    public static void main(String[] args) throws IOException {
        SpringApplication app = new SpringApplication(Gh28714Application.class);
        app.addInitializers((context) -> context.addProtocolResolver(new StringProtocolResolver()));
        Resource resource = app.run("--example.resource=string:a resource configured via a string").getBean(Gh28714Application.class).getResource();
        System.out.println(StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8));
    }

    static class StringProtocolResolver implements ProtocolResolver {

        private static final String STRING_PROTOCOL_PREFIX = "string:";

        @Override
        public Resource resolve(String location, ResourceLoader resourceLoader) {
            if (location.startsWith(STRING_PROTOCOL_PREFIX)) {
                return new ByteArrayResource(
                        location.substring(STRING_PROTOCOL_PREFIX.length()).getBytes(StandardCharsets.UTF_8));
            }
            return null;
        }

    }

}

An ApplicationContextInitializer can be registered via spring.factories so this could be implemented in a way that's largely transparent to the application. We'll keep this open to consider adding something like this to Boot itself. In the meantime, hopefully the above will be of use.

Comment From: nightswimmings

Amazing, thanks @wilkinsona !

Comment From: sysmat

It is amazing