zoukankan      html  css  js  c++  java
  • Spring 使用介绍(三)—— 资源

    一、Resource接口

    Spring提供Resource接口,代表底层外部资源,提供对底层外部资源的一致性访问接口

    public interface InputStreamSource {  
        InputStream getInputStream() throws IOException;  
    }
    public interface Resource extends InputStreamSource {  
           boolean exists();  
           boolean isReadable();  
           boolean isOpen();  
           URL getURL() throws IOException;  
           URI getURI() throws IOException;  
           File getFile() throws IOException;  
           long contentLength() throws IOException;  
           long lastModified() throws IOException;  
           Resource createRelative(String relativePath) throws IOException;  
           String getFilename();  
           String getDescription();  
    }  

    二、内置Resource实现

    1、ByteArrayResource  byte[]数组资源

    2、FileSystemResource  文件系统资源

    3、ClassPathResource  classpath路径资源

    4、UrlResource     URL资源

    • http: new UrlResource(“http://地址”)
    • ftp: new UrlResource(“ftp://地址”)
    • file: new UrlResource(“file:d:/test.txt”)

    5、ServletContextResource 代表web应用资源,简化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作

    public class ResourceTest {
        private static void dumpStream(Resource resource) throws Exception {
            if (resource.exists()) {
                InputStream is = resource.getInputStream();
                byte[] bytes = new byte[is.available()];
                is.read(bytes);
                System.out.println(new String(bytes));
            }
        }
    
        public static void main(String[] args) throws Exception {
            // byte[]数组资源
            Resource resource = new ByteArrayResource("hello world".getBytes());
            
            // 文件系统资源
            //Resource resource = new FileSystemResource("D:\hello.txt");
            
            // classpath路径资源
            //Resource resource = new ClassPathResource("durid.properties");
            
            // URL资源
            //Resource resource = new ClassPathResource("file:D:\hello.txt");
            
            dumpStream(resource);
            System.out.println(resource.getURL());
        }
    }

    三、ResourceLoader接口

    ResourceLoader接口返回Resource,可作为生产Resource的工厂类

    public interface ResourceLoader {  
           Resource getResource(String location);  
           ClassLoader getClassLoader();  
    }  

    1、ResourceLoader接口实现类:DefaultResourceLoader  通过前缀指定要加载的资源,不指定默认加载classpath资源

      • classpath:path  表示返回ClasspathResource
      • http://path 或 file:path  表示返回UrlResource资源
    public static void main(String[] args) throws Exception {
        DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource("file:D:\hello.txt");
        
        dumpStream(resource);
        System.out.println(resource.getURL());
    }

    2、ResourceLoader注入

    Spring提供ResourceLoaderAware接口,用于通过ApplicationContext上下文注入ResourceLoader,ResourceLoaderAware是一个标记接口

    public interface ResourceLoaderAware {  
       void setResourceLoader(ResourceLoader resourceLoader);  
    }  

    定义实现类,并实例化为bean

    public class ResourceBean implements ResourceLoaderAware {
    
        private ResourceLoader resourceLoader;
    
        @Override
        public void setResourceLoader(ResourceLoader resourceLoader) {
            this.resourceLoader = resourceLoader;
        }
        
        public ResourceLoader getResourceLoader() {
            return this.resourceLoader;
        }
    }
    <bean class="cn.matt.resource.ResourceBean"></bean>

    Spring检测到该接口,会将ApplicationContext注入进去

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        ResourceBean resourceBean = context.getBean(ResourceBean.class);
        System.out.println(resourceBean.getResourceLoader().getClass().getName() );
    }

    该方式属侵入性,推荐使用自动注入方式(ApplicationContext已实现ResourceLoader ,可根据类型自动注入)

    四、ResourcePatternResolver接口

    1、Ant路径通配符

    Ant路径通配符支持?、*、**:

    ?:匹配一个字符,如“config?.xml”将匹配“config1.xml”;

    *:匹配零个或多个字符串,如“cn/*/config.xml”将匹配“cn/javass/config.xml”,但不匹配匹配“cn/config.xml”;而“cn/config-*.xml”将匹配“cn/config-dao.xml”;

    **:匹配路径中的零个或多个目录,如“cn/**/config.xml”将匹配“cn /config.xml”,也匹配“cn/javass/spring/config.xml”;

      而“cn/javass/config-**.xml”将匹配“cn/javass/config-dao.xml”,即把“**”当做两个“*”处理。

    Spring提供AntPathMatcher来进行Ant风格的路径匹配

    public class AntPathMatcherTest {
        private PathMatcher pathMatcher = new AntPathMatcher();
        
        @Test
        public void testQuestionMark() {
            Assert.assertTrue(pathMatcher.match("config?.xml", "config1.xml"));
            Assert.assertFalse(pathMatcher.match("config?.xml", "config.xml"));
        }
        
        @Test
        public void testOneAsterisk() {
            Assert.assertTrue(pathMatcher.match("config-*.xml", "config-dao.xml"));
            Assert.assertTrue(pathMatcher.match("config-*.xml", "config-.xml"));
            Assert.assertTrue(pathMatcher.match("config-**.xml", "config-dao.xml"));
    
            Assert.assertTrue(pathMatcher.match("/cn/*/config.xml", "/cn/javass/config.xml"));
            Assert.assertFalse(pathMatcher.match("/cn/*/config.xml", "/cn/config.xml"));
        }
    
        @Test
        public void testTwoAsterisk() {
            Assert.assertTrue(pathMatcher.match("/cn/**/config-*.xml", "/cn/javass/config-dao.xml"));
            Assert.assertTrue(pathMatcher.match("/cn/**/config-*.xml", "/cn/javass/spring/config-dao.xml"));
            Assert.assertTrue(pathMatcher.match("/cn/**/config-*.xml", "/cn/config-dao.xml"));
        }
    }

    2、ResourcePatternResolver接口定义

    public interface ResourcePatternResolver extends ResourceLoader {  
           String CLASSPATH_ALL_URL_PREFIX = "classpath*:";  
           Resource[] getResources(String locationPattern) throws IOException;  
    }  

    ResourcePatternResolver接口继承自ResourceLoader

    PathMatchingResourcePatternResolver为其实现类,默认通过AntPathMatcher进行路径匹配,除支持‘classpath’外,还支持‘classpath*’

    1)classpath

    a、包含通配符时,可匹配当前项目的多个资源,但无法匹配依赖包中的资源

    b、无通配符时,可匹配依赖包中的资源,且仅能匹配一个资源

    @Test
    public void testResourcePatternResolver() throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        
        // 路径包含通配符时,只能匹配当前项目中的资源,但无法匹配依赖包中的资源
        Resource[] resources = resolver.getResources("classpath:META-INF/*.txt");
        Assert.assertTrue(resources.length == 2);
        Resource[] resources2 = resolver.getResources("classpath:META-INF/*.schemas");
        Assert.assertTrue(resources2.length == 0);
        
        // 路径无通配符时,可匹配依赖包中的资源
        Resource[] resources3 = resolver.getResources("classpath:META-INF/spring.schemas");
        Assert.assertTrue(resources3.length == 1);

       // 路径无通配符时,仅能匹配一个资源
       Resource[] resources4 = resolver.getResources("classpath:META-INF/license.txt");
       Assert.assertTrue(resources4.length == 1);
    // 路径包含通配符时,通配符前必须指定搜索目录,才能匹配到资源 Resource[] resources5 = resolver.getResources("classpath:*.xml"); Assert.assertTrue(resources5.length == 0);
    }

    以上示例程序运行的资源目录结构如下:

    resource(当前项目)
      |---- spring-context.xml
      |---- META-INF
        |---- license.txt
        |---- license2.txt

    spring-beans-4.2.5.RELEASE.jar(依赖包)
      |---- META-INF
        |---- spring.schemas
        |---- license.txt

    注意:ResourceLoader.getResource()接口不支持通配符(无论DefaultResourceLoader、PathMatchingResourcePatternResolver)

    @Test
    public void testResourceLoader() throws IOException {
        ResourceLoader resourceLoader = new PathMatchingResourcePatternResolver();
        
        // 存在
        Resource resource = resourceLoader.getResource("classpath:META-INF/license.txt");
        Assert.assertTrue(resource.exists());
        
        // 不存在
        Resource resource2 = resourceLoader.getResource("classpath:META-INF/*.txt");
        Assert.assertFalse(resource2.exists());
    }

    2)classpath*

    'classpath*'可加载当前项目及依赖包下的所有匹配的资源

    @Test
    public void testResourcePatternResolver2() throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("classpath*:**/*.xml");
        Assert.assertTrue(resources.length > 1);
    }

    3)file:加载一个或多个文件系统中的Resource,如“file:D:/*.txt”

    4)AppliacationContext继承自ResourcePatternResolver,其实现类的构造方法内部使用PathMatchingResourcePatternResolver,因而支持通配符

    ApplicationContext context = new ClassPathXmlApplicationContext("spring-*.xml");

    AppliacationContext的实现类:

      ClassPathXmlApplicationContext  不指定前缀将返回默认的ClassPathResource资源,否则将根据前缀来加载资源

      FileSystemXmlApplicationContext  不指定前缀将返回FileSystemResource,否则将根据前缀来加载资源

      WebApplicationContext:不指定前缀将返回ServletContextResource,否则将根据前缀来加载资源

    五、注入Resource

    1、单个资源

     Spring提供了ResourceEditor(继承自PropertyEditor ),用于在注入的字符串和Resource之间进行转换

    2、多个资源

    Spring提供了ResourceArrayPropertyEditor(继承自PropertyEditor ),用于在注入的字符串和Resource[]之间进行转换

    public class Hello {
        // 单个资源
        private Resource resource;
        
        // 多个资源
        private Resource[] resources;
    
        public Resource getResource() {
            return resource;
        }
    
        public void setResource(Resource resource) {
            this.resource = resource;
        }
    
        public Resource[] getResources() {
            return resources;
        }
    
        public void setResources(Resource[] resources) {
            this.resources = resources;
        }
    }
    <bean class="cn.matt.resource.Hello">
        <property name="resource" value="classpath:test.xml" />
        <property name="resources" value="classpath*:**/*.xml" />
    </bean>
    @Test
    public void testResourceInjection() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        Hello hello = context.getBean(Hello.class);
        
        // 单个资源
        Resource resource = hello.getResource();
        Assert.assertTrue(resource.exists());
        
        // 多个资源
        Resource[] resources = hello.getResources();
        Assert.assertTrue(resources.length > 1);
    }

    参考:

    第四章 资源 之 4.1 基础知识 ——跟我学spring3

    第四章 资源 之 4.2 内置Resource实现 ——跟我学spring3

    第四章 资源 之 4.3 访问Resource ——跟我学spring3

    第四章 资源 之 4.4 Resource通配符路径 ——跟我学spring3

  • 相关阅读:
    Bye sent_keys
    快速获取Jenkins上build
    快速搞定selenium grid分布式
    python 图形界面开发
    [分享] 自动化测试与持续集成方案-- UI 检查
    hua ge ju hao
    暴力 C++
    简单排序(java)
    记codeforces两题
    hdu 1874, dijkstra
  • 原文地址:https://www.cnblogs.com/MattCheng/p/8865287.html
Copyright © 2011-2022 走看看