zoukankan      html  css  js  c++  java
  • IOC容器的初始化过程

    这里我们以FileSystemXmlApplicationContext为例,

        public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
                throws BeansException {
    
            super(parent);
            setConfigLocations(configLocations);
            if (refresh) {
                refresh();
            }
        }

    简单来说IOC容器的初始化是通过refresh()方法来启动的,这个方法标志着IOC容器的正式启动。具体来说,这个启动包括

    BeanDefinition的Resource的定位、载人和注册三个基本过程。在分析之前,Spring把这三个过程分开,并使用不同的模块来完成,如使用相应的ResourceLoader、

    BeanDefinitionReader等模块,通过这样的设计方式,可以让用户更加灵活地对这三个过程进行裁剪和扩展,定义出最适合自己的IOC容器的初始化过程。

    第一个过程Resource定位。这个Resource指的是BeanDefinition的资源定位,它由ResourceLoader统一的Resource接口来完成,这个Resource对各种形式的BeanDefinition

    的使用都提供了统一的接口。下面清单为ResourceLoader接口定义代码:

    public interface ResourceLoader {
    
    
        String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
    
    
        Resource getResource(String location);
    
    
        ClassLoader getClassLoader();
    
    }

    对于BeanDefinition的存在形式,比如在文件系统中的Bean定义信息可以使用FileSystemResource进行抽象;在类路径中的Bean定义信息可以使用ClassPathResource来使

    用。
    第二个过程是BeanDefinition的载入。这个载入过程是把用户定义好的Bean表示成IOC容器内部的数据结构,而这个容器内部的数据结构就是BeanDefinition。具体来说。这个

    BeanDefinition实际上就是POJO对象在IOC容器中的抽象,通过这个BeanDefinition定义的数据结构,使IOC容器能够方便地对POJO对象也就是Bean进行管理。

    第三个过程是向IOC容器注册这些BeanDefinition的过程。这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的。这个注册过程中把载入过程中解析到的

    BeanDefinition向IOC容器进行注册。通过分析,在IOC容器内部将BeanDefinition注入到一个HashMap中去,IOC容器就是通过这个HashMap来持有这些BeanDefinition数据的。下面为BeanDefinitionRegistry代码清单:

    public interface BeanDefinitionRegistry extends AliasRegistry {
    
        void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;
        void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
        BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
        boolean containsBeanDefinition(String beanName);
        String[] getBeanDefinitionNames();
        int getBeanDefinitionCount();
        boolean isBeanNameInUse(String beanName);
    
    }

    值得注意的是,这里谈的是IOC容器初始化过程,在这个过程中,一般不包含Bean依赖注入实现,在IOC设计中,Bean定义的载入和依赖注入是两个独立的过程。依赖注入一般发

    生在应用第一次通过getBean向容器索取Bean的时候。但有一个例外,在IOC容器时有一个预实例化的配置,通过这个预实例化的配置(可以通过bean定义信息的lazyinit,实

    际应用中也就是spring ioc配置文件的<bean lazyinit="true">这种配置),用户可以对容器初始化过程作一个微小的控制,从而改变这个被设置lazyinit属性的Bean的依赖注入

    过程。比如,如果我们对某个Bean设置了lazyinit属性,那么这个Bean的依赖注入在IOC容器初始化时就预先完成了,而不需要等到整个初始化完成以后,第一次使用getBean时

    才会触发。

    关于定位、载入、注册的详细分析,后面会对此阐述,这里只是让需要的人了解下基本过程。

  • 相关阅读:
    codeforces C. Fixing Typos 解题报告
    codeforces B. The Fibonacci Segment 解题报告
    codeforces B. Color the Fence 解题报告
    codeforces B. Petya and Staircases 解题报告
    codeforces A. Sereja and Bottles 解题报告
    codeforces B. Levko and Permutation 解题报告
    codeforces B.Fence 解题报告
    tmp
    API 设计 POSIX File API
    分布式跟踪的一个流行标准是OpenTracing API,该标准的一个流行实现是Jaeger项目。
  • 原文地址:https://www.cnblogs.com/xiaoblog/p/4267890.html
Copyright © 2011-2022 走看看