• Spring源码之DefaultListableBeanFactory及资源载入


    1、XmlBeanFactory 的使用,参考MyEclipse Spring 学习总结一 Spring IOC容器

    public static void main(String[] args) {
            XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
            HelloWorld obj = (HelloWorld)factory.getBean("helloWorld");
            obj.getMessage();
     
        }
    

      

    2、使用DefaultListableBeanFactory和XmlBeanDefinitionReader

    ClassPathResource resource = new ClassPathSource("beans.xml");

    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

    reader.loadBeanDefinitions(resource);

    Spring加载资源并装配对象的过程

    1、定义好Spring的配置文件

    2、通过Resource将Spring配置文件进行抽象,抽象成一个Resource对象

    3、定义好Bean工厂(各种BeanFactory)

    4、定义好XmlBeanDefinitionReader对象,并将工厂对象作为参数传递进去供后续回调使用。

    5、通过XmlBeanDefinitionReader对象读取之前抽象出的Resource对象(包含了XML文件的解析过程)

    6、本质上,XML文件的解析是有XmlBeanDefinitionReader对象交由BeanDefinitionParserDelegate委托来完成的。实质上这里使用到类委托模式。

    7、Ioc容器创建完毕,用户可以通过容器获取所需的对象信息。

    3、查看ClassPathResource 

    首先查看InputStreamSource接口,里面定义了一个getInputStream方法

    public interface InputStreamSource {
    
    	/**
    	 * Return an {@link InputStream}.
    	 * <p>It is expected that each call creates a <i>fresh</i> stream.
    	 * <p>This requirement is particularly important when you consider an API such
    	 * as JavaMail, which needs to be able to read the stream multiple times when
    	 * creating mail attachments. For such a use case, it is <i>required</i>
    	 * that each <code>getInputStream()</code> call returns a fresh stream.
    	 * @throws IOException if the stream could not be opened
    	 * @see org.springframework.mail.javamail.MimeMessageHelper#addAttachment(String, InputStreamSource)
    	 */
    	InputStream getInputStream() throws IOException;
    
    }
    

      

    然后查看Resource接口

    public interface Resource extends InputStreamSource {
    
        /**
         * Return whether this resource actually exists in physical form.
         * <p>This method performs a definitive existence check, whereas the
         * existence of a <code>Resource</code> handle only guarantees a
         * valid descriptor handle.
         */
        boolean exists();
    
        /**
         * Return whether the contents of this resource can be read,
         * e.g. via {@link #getInputStream()} or {@link #getFile()}.
         * <p>Will be <code>true</code> for typical resource descriptors;
         * note that actual content reading may still fail when attempted.
         * However, a value of <code>false</code> is a definitive indication
         * that the resource content cannot be read.
         * @see #getInputStream()
         */
        boolean isReadable();
    
        /**
         * Return whether this resource represents a handle with an open
         * stream. If true, the InputStream cannot be read multiple times,
         * and must be read and closed to avoid resource leaks.
         * <p>Will be <code>false</code> for typical resource descriptors.
         */
        boolean isOpen();
    
        /**
         * Return a URL handle for this resource.
         * @throws IOException if the resource cannot be resolved as URL,
         * i.e. if the resource is not available as descriptor
         */
        URL getURL() throws IOException;
    
        /**
         * Return a URI handle for this resource.
         * @throws IOException if the resource cannot be resolved as URI,
         * i.e. if the resource is not available as descriptor
         */
        URI getURI() throws IOException;
    
        /**
         * Return a File handle for this resource.
         * @throws IOException if the resource cannot be resolved as absolute
         * file path, i.e. if the resource is not available in a file system
         */
        File getFile() throws IOException;
    
        /**
         * Determine the content length for this resource.
         * @throws IOException if the resource cannot be resolved
         * (in the file system or as some other known physical resource type)
         */
        long contentLength() throws IOException;
    
        /**
         * Determine the last-modified timestamp for this resource.
         * @throws IOException if the resource cannot be resolved
         * (in the file system or as some other known physical resource type)
         */
        long lastModified() throws IOException;
    
        /**
         * Create a resource relative to this resource.
         * @param relativePath the relative path (relative to this resource)
         * @return the resource handle for the relative resource
         * @throws IOException if the relative resource cannot be determined
         */
        Resource createRelative(String relativePath) throws IOException;
    
        /**
         * Determine a filename for this resource, i.e. typically the last
         * part of the path: for example, "myfile.txt".
         * <p>Returns <code>null</code> if this type of resource does not
         * have a filename.
         */
        String getFilename();
    
        /**
         * Return a description for this resource,
         * to be used for error output when working with the resource.
         * <p>Implementations are also encouraged to return this value
         * from their <code>toString</code> method.
         * @see java.lang.Object#toString()
         */
        String getDescription();
    
        /**
         * {@inheritDoc}
         * @return the input stream for the underlying resource (must not be {@code null}).
         */
        public InputStream getInputStream() throws IOException;
    }
    View Code

      

    4、ClassPathResource 源码

    public class ClassPathResource extends AbstractFileResolvingResource {
    
        private final String path;
    
        private ClassLoader classLoader;
    
        private Class<?> clazz;
    
    
        /**
         * Create a new ClassPathResource for ClassLoader usage.
         * A leading slash will be removed, as the ClassLoader
         * resource access methods will not accept it.
         * <p>The thread context class loader will be used for
         * loading the resource.
         * @param path the absolute path within the class path
         * @see java.lang.ClassLoader#getResourceAsStream(String)
         * @see org.springframework.util.ClassUtils#getDefaultClassLoader()
         */
        public ClassPathResource(String path) {
            this(path, (ClassLoader) null);
        }
    
        /**
         * Create a new ClassPathResource for ClassLoader usage.
         * A leading slash will be removed, as the ClassLoader
         * resource access methods will not accept it.
         * @param path the absolute path within the classpath
         * @param classLoader the class loader to load the resource with,
         * or <code>null</code> for the thread context class loader
         * @see java.lang.ClassLoader#getResourceAsStream(String)
         */
        public ClassPathResource(String path, ClassLoader classLoader) {
            Assert.notNull(path, "Path must not be null");
            String pathToUse = StringUtils.cleanPath(path);
            if (pathToUse.startsWith("/")) {
                pathToUse = pathToUse.substring(1);
            }
            this.path = pathToUse;
            this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
        }
    
        /**
         * Create a new ClassPathResource for Class usage.
         * The path can be relative to the given class,
         * or absolute within the classpath via a leading slash.
         * @param path relative or absolute path within the class path
         * @param clazz the class to load resources with
         * @see java.lang.Class#getResourceAsStream
         */
        public ClassPathResource(String path, Class<?> clazz) {
            Assert.notNull(path, "Path must not be null");
            this.path = StringUtils.cleanPath(path);
            this.clazz = clazz;
        }
    
        /**
         * Create a new ClassPathResource with optional ClassLoader and Class.
         * Only for internal usage.
         * @param path relative or absolute path within the classpath
         * @param classLoader the class loader to load the resource with, if any
         * @param clazz the class to load resources with, if any
         */
        protected ClassPathResource(String path, ClassLoader classLoader, Class<?> clazz) {
            this.path = StringUtils.cleanPath(path);
            this.classLoader = classLoader;
            this.clazz = clazz;
        }
    
        /**
         * Return the path for this resource (as resource path within the class path).
         */
        public final String getPath() {
            return this.path;
        }
    
        /**
         * Return the ClassLoader that this resource will be obtained from.
         */
        public final ClassLoader getClassLoader() {
            return (this.classLoader != null ? this.classLoader : this.clazz.getClassLoader());
        }
    
        /**
         * This implementation checks for the resolution of a resource URL.
         * @see java.lang.ClassLoader#getResource(String)
         * @see java.lang.Class#getResource(String)
         */
        @Override
        public boolean exists() {
            URL url;
            if (this.clazz != null) {
                url = this.clazz.getResource(this.path);
            }
            else {
                url = this.classLoader.getResource(this.path);
            }
            return (url != null);
        }
    
        /**
         * This implementation opens an InputStream for the given class path resource.
         * @see java.lang.ClassLoader#getResourceAsStream(String)
         * @see java.lang.Class#getResourceAsStream(String)
         */
        public InputStream getInputStream() throws IOException {
            InputStream is;
            if (this.clazz != null) {
                is = this.clazz.getResourceAsStream(this.path);
            }
            else {
                is = this.classLoader.getResourceAsStream(this.path);
            }
            if (is == null) {
                throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
            }
            return is;
        }
    
        /**
         * This implementation returns a URL for the underlying class path resource.
         * @see java.lang.ClassLoader#getResource(String)
         * @see java.lang.Class#getResource(String)
         */
        @Override
        public URL getURL() throws IOException {
            URL url;
            if (this.clazz != null) {
                url = this.clazz.getResource(this.path);
            }
            else {
                url = this.classLoader.getResource(this.path);
            }
            if (url == null) {
                throw new FileNotFoundException(getDescription() + " cannot be resolved to URL because it does not exist");
            }
            return url;
        }
    
        /**
         * This implementation creates a ClassPathResource, applying the given path
         * relative to the path of the underlying resource of this descriptor.
         * @see org.springframework.util.StringUtils#applyRelativePath(String, String)
         */
        @Override
        public Resource createRelative(String relativePath) {
            String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);
            return new ClassPathResource(pathToUse, this.classLoader, this.clazz);
        }
    
        /**
         * This implementation returns the name of the file that this class path
         * resource refers to.
         * @see org.springframework.util.StringUtils#getFilename(String)
         */
        @Override
        public String getFilename() {
            return StringUtils.getFilename(this.path);
        }
    
        /**
         * This implementation returns a description that includes the class path location.
         */
        public String getDescription() {
            StringBuilder builder = new StringBuilder("class path resource [");
    
            String pathToUse = path;
    
            if (this.clazz != null && !pathToUse.startsWith("/")) {
                builder.append(ClassUtils.classPackageAsResourcePath(this.clazz));
                builder.append('/');
            }
    
            if (pathToUse.startsWith("/")) {
                pathToUse = pathToUse.substring(1);
            }
    
            builder.append(pathToUse);
            builder.append(']');
            return builder.toString();
        }
    
        /**
         * This implementation compares the underlying class path locations.
         */
        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (obj instanceof ClassPathResource) {
                ClassPathResource otherRes = (ClassPathResource) obj;
                return (this.path.equals(otherRes.path)
                        && ObjectUtils.nullSafeEquals(this.classLoader, otherRes.classLoader) && ObjectUtils.nullSafeEquals(
                    this.clazz, otherRes.clazz));
            }
            return false;
        }
    
        /**
         * This implementation returns the hash code of the underlying
         * class path location.
         */
        @Override
        public int hashCode() {
            return this.path.hashCode();
        }
    
    }
    View Code
  • 相关阅读:
    js数组与字符串的相互转换方法
    js页面跳转常用的几种方式
    js刷新页面方法大全
    IIS上开启反向代理实现Vue项目接口跨域处理
    【问题解决记录】vue解决低版本安卓与ios10以下系统兼容性问题
    【解决问题记录】https网站中请求http资源接口报错与netERRSSLPROTOCOLERROR错误的解决
    indexedDb数据库基本操作
    Object常用方法
    htmlToTex
    禁止鼠标右键保存/拖动/选中/复制 图片/文字
  • 原文地址:https://www.cnblogs.com/linlf03/p/11116799.html
Copyright © 2020-2023  润新知