java 标准资源管理
职责 | 说明 |
---|---|
面向资源 | 文件系统、artifact(jar、war、ear文件)以及远程资源(HTTP、FTP等) |
API整合 | ClassLoader#getResource、java.io.File、java.net.URL |
资源定位 | java.net.URL、java.net.URI |
面向流式存储 | java.net.URLConnection |
协议扩展 | java.net.URLStreamHandler 或 java.net.URLStreamHandlerFactory |
基于java.net.URLStreamHandler
扩展协议:jdk1.8内建协议实现,
自定义URLStreamHandler
对象,可以通过以下俩种方式注入到URL中:
- 设置自定义的
URLStreamHandler
类名为Handler
,然后在程序启动的时候加上-Djava.protocol.handler.pkgs="Handler所在包名"
参数,如果存在多个包名指定,可以通过分隔符"|" - 自定义
java.net.URLStreamHandlerFactory
,然后通过URL#setURLStreamHandlerFactory
设置
具体原理可参考:URL#getURLStreamHandler(String)
方法源码
Spring资源管理接口
类型 | 接口 |
---|---|
输入流 | org.springframework.core.io.InputStreamSource |
只读资源 | org.springframework.core.io.Resource |
可写资源 | org.springframework.core.io.WritableResource |
编码资源 | org.springframework.core.io.support.EncodedResource |
上下文资源 | org.springframework.core.io.ContextResource |
Spring资源加载器
下面列举了三个常见的资源加载器实现,通过资源加载器加载对应的资源
测试:
public class FileSystemResourceLoaderDemo {
public static void main(String[] args) throws IOException {
String filePath = System.getProperty("user.dir") + "/spring-framework/spring-core/src/main/java/com/wj/resource/FileSystemResourceLoaderDemo.java";
FileSystemResourceLoader resourceLoader = new FileSystemResourceLoader();
Resource resource = resourceLoader.getResource(filePath);
EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
Reader reader = encodedResource.getReader();
System.out.println(FileCopyUtils.copyToString(reader));
}
}
打印结果:
spring通配路径资源加载器
通配路径:
org.springframework.core.io.support.ResourcePatternResolver
org.springframework.core.io.support.PathMatchingResourcePatternResolver
路径匹配器:
org.springframework.util.PathMatcher
- Ant模式匹配:
org.springframework.util.AntPathMatcher
- Ant模式匹配:
可以通过通配路径资源加载器获取到所有匹配的资源:
示例如下:获取指定路径下的所有java文件
public class ResourcePatternResolverDemo {
public static void main(String[] args) throws IOException {
String filePath = System.getProperty("user.dir") + "/spring-framework/spring-core/src/main/java/com/wj/";
String pattern = "**/*.java";
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver(new FileSystemResourceLoader());
Resource[] resources = patternResolver.getResources(filePath + pattern);
for (Resource resource : resources) {
System.out.println(resource.getFile().getName());
}
}
}
依赖注入Spring Resource
我在resource下面放了一个属性配置文件:
代码示例:
@Configuration
public class ResourceInjectDemo {
@Value(ResourceUtils.CLASSPATH_URL_PREFIX + "resource.properties")
private Resource resource;
public Resource getResource() {
return resource;
}
public static void main(String[] args) throws IOException {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ResourceInjectDemo.class);
ResourceInjectDemo demo = applicationContext.getBean(ResourceInjectDemo.class);
EncodedResource encodedResource = new EncodedResource(demo.getResource(), "UTF-8");
Reader reader = encodedResource.getReader();
System.out.println(FileCopyUtils.copyToString(reader));
}
}
这里通过@Value的形式就可以注入Resource对象到Bean中。
简单说明一下原理,spring通过
AutowiredAnnotationBeanPostProcessor
后置处理器处理bean中的@Value
注解,获取到注解的value
值,然后通过TypeConverter
类型转换器,实际上通过的是ResourceEditor
将String
类型转换成Resource
,最后通过反射注入。在
ResourceEditor
中使用的就是ResourceLoader
去加载Resource
。
此外,还可以注入数组类型Resource
:
@Value(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "*.properties")
private Resource[] resources;
原理与前面类似,只不过最后类型转换使用的是
ResourceArrayPropertyEditor
,而该类中使用的就是前面说到的PathMatchingResourcePatternResolver
去路径匹配,
关于类型转换详细原理可参考我前面的博客:
ResourceLoader依赖注入
- ResourceLoaderAware回调
- @Autowired注入ResourceLoader
- 直接注入ApplicationContext,因为ApplicationContext实现了ResourceLoader
示例不就写了,比较简单。
原理解释:
spring容器在启动的时候,调用了prepareBeanFactory方法中,有这么几行:
这几行说明 Spring在依赖注入的时候,当需要注入这四个类型的接口时,会把设置的指定对象注入进去,这里ResourceLoader指定的对象就是ApplicationContext。
依赖注入的代码:
ResourceLoaderAware的原理就更简单了:主要通过ApplicationContextAwareProcessor后置处理器进行设置,
标签:core,resource,Spring,Resource,springframework,org,java,资源管理 From: https://www.cnblogs.com/wwjj4811/p/16966332.html