zoukankan      html  css  js  c++  java
  • 【sping揭秘】6、IOC容器之统一资源加载策略

    Spring中的resource

    我们先看看类之间的关系

    注意我们的application是间接继承了resourceloader的,也就是说我们的application其实就是一个resourceloader

    我们再看看这个类的继承,发现了,classpathxml这个对象实际上也是从最开始的resourceloader来的

    那么我们加载application资源的时候,可以有2种方式:

    ResourceLoader resourceLoader = new ClassPathXmlApplicationContext("classpath:applicationContext-bean.xml");
            //第二种方式
    ResourceLoader resourceLoader2 = new FileSystemXmlApplicationContext("classpath:applicationContext-bean.xml");

    都是可以的哈,都是可以的!!!

    那这个resourceloader有什么用???

    关键就是那个getResource(String)方法,获取资源

    自然而然,我们会想,这个能获取什么资源,怎么去获取资源,嗯。。。

    具体怎么获取我们继续看书。。。

    在搞清除怎么获取资源之前,我们想一下如何去获取这个resourceloader,如果我们每次获取都要用new ClassPathXmlApplicationContext或者new FileSystemXmlApplicationContext

    获取这个对象的方法spring也有提供,我们只要实现ResourceLoaderAware或者ApplicationContextAware就可以实现了(因为applicationContext也是resourceloader的一种,参考上面的UML图

    Public class FooBar implements ResourceLoaderAware {
        
        //资源加载器
        private ResourceLoader resourceLoader;
        
        public void foo(String location) {
            //这里有没有很熟悉
    //        ResourceDemo.class.getResource(location).getClass()
            System.out.println(this.getResourceLoader().getResource(location).getClass());
        }
    
        @Override
        public void setResourceLoader(ResourceLoader resourceLoader) {
            //这里进行resourceloader的注入
            this.resourceLoader = resourceLoader;
        }
    
        public ResourceLoader getResourceLoader() {
            return resourceLoader;
        }
        
    }
    
    
    Public class FooBar2 implements ApplicationContextAware {
        
        //资源加载器
        private ResourceLoader resourceLoader;
        
        public void foo(String location) {
            //这里有没有很熟悉
    //        ResourceDemo.class.getResource(location).getClass()
            System.out.println(this.getResourceLoader().getResource(location).getClass());
        }
    
        public ResourceLoader getResourceLoader() {
            return resourceLoader;
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            // TODO Auto-generated method stub
            //这里进行resourceloader的注入
            this.resourceLoader = applicationContext;
        }
        
    }

    然后我们需要在对应的配置文件中配置好这个bean,那spring就会自动为这个bean注入resource了

    <bean id="fooBar" class="cn.cutter.start.resourceloader.FooBar" />
        
    <bean id="fooBar2" class="cn.cutter.start.resourceloader.FooBar2" />

    好吧,看到这里是不是有点晕了,到底resourceloader和resource是什么玩意???

    我们先放下书,冷静一下,想一下这到底是个啥玩意,有啥作用???

    前面resourceloader我们看到了可以用来加载资源,可以加载spring配置文件,那么resource呢?

    我们的resource是可以通过resourceloader中的get方法获取,那么不同的resourceloader是不是会获取到不同的resource呢?

    我们先从默认的defaultresourceloader方法看起

     

    这个类也很光棍,既然要返回那么就直接返回resource算了,反正也是接口实现的

    那么我们可以看看可以返回那些resource,是不是不同的策略可以返回不同的resource

     ClassPathResource可用来获取类路径下的资源文件。假设我们有一个资源文件test.txt在类路径下,我们就可以通过给定对应资源文件在类路径下的路径path来获取它,new ClassPathResource(“test.txt”)。

     FileSystemResource可用来获取文件系统里面的资源。我们可以通过对应资源文件的文件路径来构建一个FileSystemResource。FileSystemResource还可以往对应的资源文件里面写内容,当然前提是当前资源文件是可写的,这可以通过其isWritable()方法来判断。FileSystemResource对外开放了对应资源文件的输出流,可以通过getOutputStream()方法获取到。

     UrlResource可用来代表URL对应的资源,它对URL做了一个简单的封装。通过给定一个URL地址,我们就能构建一个UrlResource。

    ByteArrayResource是针对于字节数组封装的资源,它的构建需要一个字节数组。

    ServletContextResource是针对于ServletContext封装的资源,用于访问ServletContext环境下的资源。ServletContextResource持有一个ServletContext的引用,其底层是通过ServletContext的getResource()方法和getResourceAsStream()方法来获取资源的。

    InputStreamResource是针对于输入流封装的资源,它的构建需要一个输入流。

    可以看得出来,这类resource可以看成相应的资源,借助java的io流,我们可以获取对应的资源的输入流,那么通过io流就就可以获取到对应的资源,不论是类,文件,还是字节流,都可以看成不同的资源

    那么这些跟spring有什么关系呢???

    我们实体操作一个

    package cn.cutter.start.resourceloader;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    import org.springframework.core.io.Resource;
    
    /**
     * 用来测试spring的统一资源加载策略
     * @author xiaof
     *
     */
    public class ResourceDemo {
    
        private Resource resource;
        
        public void printContent() {
            if (resource != null && resource.exists()) {
                if (resource.isReadable()) {
                    InputStream is;
                    try {
                        is = resource.getInputStream();
                        BufferedReader br = new BufferedReader(new InputStreamReader(is));
                        String line;
                        while ((line = br.readLine()) != null) {
                            System.out.println(line);
                        }
                        if (is != null) {
                            is.close();
                        }
                        if (br != null) {
                            br.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        public void setResource(Resource resource) {
            this.resource = resource;
        }
        
    }

    Spring配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    
        <context:component-scan base-package="cn.cutter"  />
        
        <bean id="ttmRateService" class="cn.cutter.simplefx.service.impl.MockTTMRateServiceImpl"></bean>
        
        <bean id="fooBar" class="cn.cutter.start.resourceloader.FooBar" />
        
        <bean id="fooBar2" class="cn.cutter.start.resourceloader.FooBar2" />
        
        <bean id="resourceDemo" class="cn.cutter.start.resourceloader.ResourceDemo">
            <property name="resource">
                <value>classpath:applicationContext-bean.xml</value>
            </property>
        </bean>
        
        
    </beans>

    测试案例:

    @Test
        public void testPrintContext() {
            ApplicationContext ctx = before();
            
            ResourceDemo resourceDemo = (ResourceDemo) ctx.getBean("resourceDemo");
            
            resourceDemo.printContent();
            
        }

    结果展示:

     

    我们看得到,这个资源其实就是输出这个文件流内容。

  • 相关阅读:
    微信公众平台开发文档 生成带参数的二维码
    微信公众平台开发文档 获取用户地理位置
    文件上传控件-如何上传文件-文件夹下载
    文件上传控件-如何上传文件-大文件下载
    文件上传控件-如何上传文件-文件夹层级结构
    文件上传控件-如何上传文件-文件夹断点续传
    文件上传控件-如何上传文件-文件夹上传
    文件上传控件-如何上传文件-大文件断点续传
    文件上传控件-如何上传文件-大文件上传
    文件夹上传插件webupload插件
  • 原文地址:https://www.cnblogs.com/cutter-point/p/8626713.html
Copyright © 2011-2022 走看看