spring源码(十六)--ClassPathXmlApplicationContext

在这里插入图片描述
ClassPathXmlApplicationContext是应用的起点,通常调用下面的构造函数,参数为配置文件的地址

 public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[]{configLocation}, true, (ApplicationContext)null);
    }

创建一个classpathXmlApplicationContext对象时,初步分2步,设置配置文件地址,启动应用。

	    this.setConfigLocations(configLocations);
        this.refresh(); //调用父类AbstractApplicationContext

refresh()解析:

  • 第一步,prepareRefresh();非web应用,只是初始化了一些变量(closed,active)的值
  • 第二步,obtainFreshBeanFactory();创建beanFactory.
    refreshBeanFactory(),刷新beanFactory,如果已经有,
    destroyBeans(),closeBeanFactory()。
    createBeanFactory(),直接使用context的id作为新beanFactory的id。
    this.loadBeanDefinitions(beanFactory);
  • 第三步,

第二步:

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();//基本设置,可以忽略
            
            //创建DefaultListableBeanFactory,设置ID为applicationContext的id
            //loadBeanDefinitions,加载bean的定义,
            //把所有的bean定义加载到Map<String, BeanDefinition> beanDefinitionMap
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            
            //注册一些依赖的bean
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
--- 虚线内为其它方法
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//添加到beanPostProcessors中,这是 一个list
        beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));

//添加到ignoredDependencyInterfaces,这是一个set
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

//注册request,session,globalSession,application四个scope到beanFactory的scopes(这是一个map)中,ServletRequest,ServletResponse,HttpSession等(factory型的)注册到resolvableDependencies(也是map)中
        WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);

//注册servletContext,servletConfig,contextParameters,contextAttributes等到spring容器中
        WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
    }

---
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);

//创建一个messageSource到容器中
                this.initMessageSource();
                //创建applicationEventMulticaster到容器中
                this.initApplicationEventMulticaster();
                
                this.onRefresh();
                this.registerListeners();

//这里会实例化所有非延迟加载的bean实例
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if(this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

其中obtainFreshBeanFactory();调用XmlWebApplicationContext的loadBeanDefinitions,一路下去,直到XmlBeanDefinitionReader的loadBeanDefinitions,也就是第三篇的核心内容。这条线,作用就是解析配置文件,把符合条件的beanDefinition注册到factory中。

 protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        return this.getBeanFactory();
    }

在refreshBeanFactory();中,先判断有没有beanfactory,有的话,先去除引用。

if(this.hasBeanFactory()) {
            this.destroyBeans();//第十七篇中
            this.closeBeanFactory();//beanFactory置为null,id置为null。serializableFactories(静态常量,DefaultListableBeanFactory的)中移除这个beanfactory的弱引用。
        }

创建一个DefaultListableBeanFactory实例,如果有parent,则把parent的bf也传递过来。

  DefaultListableBeanFactory beanFactory = this.createBeanFactory();

给bf一个id,采用的系统默认hashcode实现,所以对于这个对象基本上不会重复。然后会把bf放到一个static的map中,使用弱引用包裹。

beanFactory.setSerializationId(this.getId());

AbstractRefreshableApplicationContext的loadBeanDefinitions(beanfactory),这是关键方法,在其他篇中详解
至此,AbstractRefreshableApplicationContext的refreshBeanFactory解析完毕,getBefactory获得的也是这个factory。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值