Spring IoC容器的初始化包括 BeanDefinition的Resource定位、载入和注册 这三个基本的过程。IoC容器的初始化过程不包含Bean依赖注入的实现。Bean依赖的注入一般会发生在第一次通过getBean向容器索取Bean的时候。

先看以下代码:

ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml");
Car car = (Car) context.getBean("car");
System.out.println(car.getBrand());

以上是我们常用的加载IoC容器,并获得Bean的代码。直接进入ClassPathXmlApplicationContext的构造方法,它实际调用的构造方法为:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {

    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();    //调用容器的refresh,载入BeanDefinitionde的入口。
    }
}
调用super(parent)方法为容器设置好Bean资源加载器,该方法最终会调用到AbstractApplicationContext的无参构造方法,这里会默认设置解析路径的模式为Ant-style。
setConfigLocations(configLocations)设置Bean定义资源文件的定位路径。AbstractRefreshableConfigApplicationContext中的setConfigLocation(String location)说明了多个资源文件路径之间可以是用” ,
; /t/n”分隔。setConfigLocations(String… locations)说明了它还接受字符串数组。

接下来看下最重要的refresh()方法。

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识  
        prepareRefresh();

        // 通知子类启动refreshBeanFactory()的调用
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        //为BeanFactory配置容器特性,例如类加载器、事件处理器等  
        prepareBeanFactory(beanFactory);

        try {
            //为子类设置BeanFactory的后置处理器
            postProcessBeanFactory(beanFactory);

            //调用BeanFactoryPostProcessor,这些后置处理器都是在Bean定义中向容器定义的
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注册Bean的后置处理器,在Bean创建过程中调用
            registerBeanPostProcessors(beanFactory);

            // 对上下文的消息源进行初始化
            initMessageSource();

            // 初始化上下文的事件机制
            initApplicationEventMulticaster();

            // 初始化其他特殊的Bean
            onRefresh();

            // 检查监听Bean,并且将这些Bean向容器中注册
            registerListeners();

            // 实例化所有的(non-lazy-init) 单例
            finishBeanFactoryInitialization(beanFactory);

            // 最后一步:发布容器事件,结束refresh过程
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            /销毁已经创建的单态Bean  
            destroyBeans();

            // 重置'active'状态
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}
View Code

相关文章:

  • 2022-12-23
  • 2022-02-17
  • 2022-12-23
  • 2021-09-29
  • 2021-05-07
  • 2021-08-22
  • 2021-10-13
  • 2021-09-05
猜你喜欢
  • 2022-01-29
  • 2021-10-13
  • 2022-12-23
  • 2022-12-23
  • 2021-07-28
  • 2022-01-08
相关资源
相似解决方案