Spring Framework Core - IoC Container and Dependency Injection
—
Spring Core provides a comprehensive abstraction for accessing resources from various sources including classpath, file system, URLs, and in-memory data. This unified API simplifies resource handling across different deployment scenarios.
The Resource interface provides the fundamental abstraction for all resource types.
Resource Interface
public interface Resource extends InputStreamSource {
boolean exists();
default boolean isReadable();
default boolean isOpen();
default boolean isFile();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
default ReadableByteChannel readableChannel() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
// From InputStreamSource
InputStream getInputStream() throws IOException;
}
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}Writable Resource Extension
public interface WritableResource extends Resource {
default boolean isWritable();
OutputStream getOutputStream() throws IOException;
default WritableByteChannel writableChannel() throws IOException;
}Usage Examples
// Basic resource operations
Resource resource = new ClassPathResource("config/application.properties");
// Check resource existence and properties
if (resource.exists() && resource.isReadable()) {
long size = resource.contentLength();
long modified = resource.lastModified();
String filename = resource.getFilename(); // "application.properties"
// Read content
try (InputStream input = resource.getInputStream()) {
Properties props = new Properties();
props.load(input);
}
}
// Get file system representation
if (resource.isFile()) {
File file = resource.getFile();
Path path = file.toPath();
}
// Create relative resources
Resource siblingResource = resource.createRelative("../logging/logback.xml");Spring provides several concrete Resource implementations for different source types.
ClassPath Resources
public class ClassPathResource extends AbstractFileResolvingResource {
public ClassPathResource(String path);
public ClassPathResource(String path, Class<?> clazz);
public ClassPathResource(String path, ClassLoader classLoader);
public final String getPath();
public final ClassLoader getClassLoader();
@Override
public boolean exists();
@Override
public InputStream getInputStream() throws IOException;
@Override
public URL getURL() throws IOException;
@Override
public String getDescription();
}File System Resources
public class FileSystemResource extends AbstractResource implements WritableResource {
public FileSystemResource(String path);
public FileSystemResource(File file);
public FileSystemResource(Path filePath);
public final String getPath();
public final File getFile();
@Override
public boolean exists();
@Override
public boolean isReadable();
@Override
public InputStream getInputStream() throws IOException;
@Override
public boolean isWritable();
@Override
public OutputStream getOutputStream() throws IOException;
@Override
public String getDescription();
}URL Resources
public class UrlResource extends AbstractFileResolvingResource {
public UrlResource(URL url);
public UrlResource(String location) throws MalformedURLException;
public UrlResource(String protocol, String location) throws MalformedURLException;
@Override
public InputStream getInputStream() throws IOException;
@Override
public URL getURL();
@Override
public URI getURI() throws IOException;
@Override
public boolean exists();
@Override
public String getDescription();
}Byte Array Resources
public class ByteArrayResource extends AbstractResource {
public ByteArrayResource(byte[] byteArray);
public ByteArrayResource(byte[] byteArray, String description);
public final byte[] getByteArray();
@Override
public boolean exists();
@Override
public long contentLength();
@Override
public InputStream getInputStream();
@Override
public String getDescription();
}Usage Examples
// ClassPath resources
Resource configResource = new ClassPathResource("application.yml");
Resource templatesDir = new ClassPathResource("templates/", MyClass.class);
Resource libResource = new ClassPathResource("lib/helper.jar", classLoader);
// File system resources
Resource dataFile = new FileSystemResource("/data/users.csv");
Resource tempFile = new FileSystemResource(Files.createTempFile("temp", ".txt"));
// Write to file system resource
if (dataFile instanceof WritableResource writable && writable.isWritable()) {
try (OutputStream output = writable.getOutputStream()) {
output.write("New data".getBytes());
}
}
// URL resources
Resource remoteConfig = new UrlResource("https://config.example.com/app.properties");
Resource jarResource = new UrlResource("jar:file:/app/lib/data.jar!/config.xml");
// Byte array resources (useful for testing)
byte[] data = "Test configuration".getBytes();
Resource memoryResource = new ByteArrayResource(data, "test-config");Spring provides a strategy-based approach for loading resources with support for location patterns.
ResourceLoader Interface
public interface ResourceLoader {
String CLASSPATH_URL_PREFIX = "classpath:";
Resource getResource(String location);
ClassLoader getClassLoader();
}
public class DefaultResourceLoader implements ResourceLoader {
public DefaultResourceLoader();
public DefaultResourceLoader(ClassLoader classLoader);
public void setClassLoader(ClassLoader classLoader);
@Override
public ClassLoader getClassLoader();
@Override
public Resource getResource(String location);
public void addProtocolResolver(ProtocolResolver protocolResolver);
public Collection<ProtocolResolver> getProtocolResolvers();
public void clearProtocolResolvers();
protected Resource getResourceByPath(String path);
}Pattern-Based Resource Loading
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
Resource[] getResources(String locationPattern) throws IOException;
}
public class PathMatchingResourcePatternResolver
implements ResourcePatternResolver, Ordered {
public PathMatchingResourcePatternResolver();
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader);
public PathMatchingResourcePatternResolver(ClassLoader classLoader);
public void setPathMatcher(PathMatcher pathMatcher);
public PathMatcher getPathMatcher();
@Override
public Resource getResource(String location);
@Override
public Resource[] getResources(String locationPattern) throws IOException;
@Override
public int getOrder();
}Protocol Resolver Extension
@FunctionalInterface
public interface ProtocolResolver {
Resource resolve(String location, ResourceLoader resourceLoader);
}Usage Examples
// Basic resource loading
ResourceLoader loader = new DefaultResourceLoader();
// Load from different sources based on prefix
Resource classpathResource = loader.getResource("classpath:config.properties");
Resource fileResource = loader.getResource("file:./data.txt");
Resource urlResource = loader.getResource("https://example.com/config.json");
// Pattern-based loading
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// Load all matching resources from classpath
Resource[] configFiles = resolver.getResources("classpath*:config/*.properties");
Resource[] xmlFiles = resolver.getResources("classpath:spring/**/*.xml");
Resource[] allJars = resolver.getResources("classpath*:lib/*.jar");
// Process multiple resources
for (Resource resource : configFiles) {
if (resource.exists()) {
Properties props = new Properties();
try (InputStream input = resource.getInputStream()) {
props.load(input);
}
System.out.println("Loaded: " + resource.getDescription());
}
}
// Custom protocol resolver
loader.addProtocolResolver((location, resourceLoader) -> {
if (location.startsWith("custom:")) {
String path = location.substring(7);
return new FileSystemResource("/custom/path/" + path);
}
return null;
});
Resource customResource = loader.getResource("custom:myfile.txt");Resource Utility Classes
public abstract class ResourceUtils {
public static final String CLASSPATH_URL_PREFIX = "classpath:";
public static final String FILE_URL_PREFIX = "file:";
public static final String JAR_URL_PREFIX = "jar:";
public static final String WAR_URL_PREFIX = "war:";
public static boolean isUrl(String resourceLocation);
public static URL getURL(String resourceLocation) throws FileNotFoundException;
public static File getFile(String resourceLocation) throws FileNotFoundException;
public static File getFile(URL resourceUrl) throws FileNotFoundException;
public static File getFile(URI resourceUri) throws FileNotFoundException;
public static boolean isFileURL(URL url);
public static boolean isJarURL(URL url);
public static boolean isJarFileURL(URL url);
public static URL extractJarFileURL(URL jarUrl) throws MalformedURLException;
public static URL extractArchiveURL(URL jarUrl) throws MalformedURLException;
public static URI toURI(URL url) throws URISyntaxException;
public static URI toURI(String location) throws URISyntaxException;
}Usage Examples
// Check resource location types
boolean isUrl = ResourceUtils.isUrl("https://example.com/file.txt"); // true
boolean isClasspath = ResourceUtils.isUrl("classpath:config.xml"); // false
// Get File objects from resource locations
File configFile = ResourceUtils.getFile("classpath:application.properties");
File dataFile = ResourceUtils.getFile("file:/data/users.csv");
// Work with JAR URLs
URL jarUrl = new URL("jar:file:/app/lib/mylib.jar!/config.xml");
boolean isJar = ResourceUtils.isJarURL(jarUrl); // true
URL jarFileUrl = ResourceUtils.extractJarFileURL(jarUrl); // file:/app/lib/mylib.jarContext-Aware Resources
public interface ContextResource extends Resource {
String getPathWithinContext();
}
public interface HttpResource extends Resource {
HttpHeaders getResponseHeaders();
}File-Based Resource Extensions
public abstract class AbstractFileResolvingResource extends AbstractResource {
@Override
public boolean exists();
@Override
public boolean isReadable();
@Override
public boolean isFile();
@Override
public File getFile() throws IOException;
@Override
public ReadableByteChannel readableChannel() throws IOException;
@Override
public long contentLength() throws IOException;
@Override
public long lastModified() throws IOException;
protected File getFileForLastModifiedCheck() throws IOException;
protected boolean isFile(URI uri);
protected File getFile(URI uri) throws IOException;
protected File getFile(URL url) throws IOException;
}
public abstract class AbstractResource implements Resource {
@Override
public boolean exists();
@Override
public boolean isReadable();
@Override
public boolean isOpen();
@Override
public boolean isFile();
@Override
public URL getURL() throws IOException;
@Override
public URI getURI() throws IOException;
@Override
public File getFile() throws IOException;
@Override
public ReadableByteChannel readableChannel() throws IOException;
@Override
public long contentLength() throws IOException;
@Override
public long lastModified() throws IOException;
@Override
public Resource createRelative(String relativePath) throws IOException;
@Override
public String getFilename();
// Utility methods
public String toString();
public boolean equals(Object other);
public int hashCode();
}Input Stream Source Chain
public class InputStreamResource extends AbstractResource {
public InputStreamResource(InputStream inputStream);
public InputStreamResource(InputStream inputStream, String description);
@Override
public String getDescription();
@Override
public InputStream getInputStream() throws IOException;
@Override
public boolean equals(Object other);
@Override
public int hashCode();
}Encoded Resources
public class EncodedResource implements InputStreamSource {
public EncodedResource(Resource resource);
public EncodedResource(Resource resource, String encoding);
public EncodedResource(Resource resource, Charset charset);
public final Resource getResource();
public final String getEncoding();
public final Charset getCharset();
public boolean requiresReader();
public Reader getReader() throws IOException;
@Override
public InputStream getInputStream() throws IOException;
}Usage Examples
// Work with encoded resources
Resource xmlResource = new ClassPathResource("data/users.xml");
EncodedResource encodedXml = new EncodedResource(xmlResource, "UTF-8");
// Read as character stream
try (Reader reader = encodedXml.getReader()) {
// Parse XML with proper encoding
}
// Input stream resource (useful for wrapping existing streams)
InputStream dataStream = getDataFromSomewhere();
Resource streamResource = new InputStreamResource(dataStream, "external-data");
// Use in Spring configurations
@Bean
public Properties applicationProperties() throws IOException {
Properties props = new Properties();
Resource resource = new ClassPathResource("application.properties");
props.load(resource.getInputStream());
return props;
}Path Matcher Interface
public interface PathMatcher {
boolean isPattern(String path);
boolean match(String pattern, String path);
boolean matchStart(String pattern, String path);
String extractPathWithinPattern(String pattern, String path);
Map<String, String> extractUriTemplateVariables(String pattern, String path);
Comparator<String> getPatternComparator(String path);
String combine(String pattern1, String pattern2);
}
public class AntPathMatcher implements PathMatcher {
public static final String DEFAULT_PATH_SEPARATOR = "/";
public AntPathMatcher();
public AntPathMatcher(String pathSeparator);
public void setPathSeparator(String pathSeparator);
public void setCaseSensitive(boolean caseSensitive);
public void setTrimTokens(boolean trimTokens);
public void setCachePatterns(boolean cachePatterns);
@Override
public boolean isPattern(String path);
@Override
public boolean match(String pattern, String path);
@Override
public boolean matchStart(String pattern, String path);
@Override
public String extractPathWithinPattern(String pattern, String path);
@Override
public Map<String, String> extractUriTemplateVariables(String pattern, String path);
@Override
public Comparator<String> getPatternComparator(String path);
@Override
public String combine(String pattern1, String pattern2);
}Usage Examples
// Pattern matching with AntPathMatcher
PathMatcher matcher = new AntPathMatcher();
// Test patterns
boolean matches1 = matcher.match("*.txt", "readme.txt"); // true
boolean matches2 = matcher.match("/config/**/*.xml", "/config/prod/db.xml"); // true
boolean matches3 = matcher.match("/api/{version}/users", "/api/v1/users"); // true
// Extract path variables
Map<String, String> variables = matcher.extractUriTemplateVariables(
"/users/{userId}/posts/{postId}",
"/users/123/posts/456"
);
// Returns: {userId=123, postId=456}
// Extract path within pattern
String extracted = matcher.extractPathWithinPattern(
"/static/**",
"/static/css/style.css"
);
// Returns: "css/style.css"
// Combine patterns
String combined = matcher.combine("/api/**", "*.json"); // "/api/**/*.json"This comprehensive resource management system provides the foundation for Spring's configuration loading, template resolution, static resource serving, and many other framework features that need to access resources from various sources in a consistent manner.
Install with Tessl CLI
npx tessl i tessl/maven-org-springframework--spring-core