大家好,我是程序员田同学

上篇文章对spring外围启动办法refresh做了整体的解读,然而只是泛泛而谈,接下来会出一零碎文章对每个办法的源码进行粗浅解读。

第一篇文章见 spring源码之办法概览

首先,第一个办法是prepareRefresh()办法,这个办法做的事很简略,也不是本文的重点。该办法记录容器的启动工夫,初始化监听容器。

protected void prepareRefresh() {        // Switch to active        //纪录启动工夫        this.startupDate = System.currentTimeMillis();        System.out.println("spring启动工夫为--------------------" + this.startupDate);        this.closed.set(false);        System.out.println("spring标记为未敞开--------------------" + this.closed);        this.active.set(true);        System.out.println("spring以后激活状态--------------------" + this.active);         if (logger.isDebugEnabled()) {            if (logger.isTraceEnabled()) {                logger.trace("Refreshing " + this);            } else {                logger.debug("Refreshing " + getDisplayName());            }        }        // Initialize any placeholder property sources in the context environment.        //空办法        initPropertySources();         // Validate that all properties marked as required are resolvable:        // see ConfigurablePropertyResolver#setRequiredProperties        //校验 xml配置文件        getEnvironment().validateRequiredProperties();         // Store pre-refresh ApplicationListeners...        //初始化applicationListeners监听容器        if (this.earlyApplicationListeners == null) {            this.earlyApplicationListeners = new LinkedHashSet<>              (this.applicationListeners);        } else {            // Reset local application listeners to pre-refresh state.            this.applicationListeners.clear();            this.applicationListeners.addAll(this.earlyApplicationListeners);        }         // Allow for the collection of early ApplicationEvents,        // to be published once the multicaster is available...        this.earlyApplicationEvents = new LinkedHashSet<>();    }    

读者大抵搂一眼即可,对这个办法整体就能很快把握。

接下来才是明天的重头戏——obtainFreshBeanFactory()办法,是refresh()办法中的第二个办法,也是整个refresh()办法中外围办法之一。

该办法次要的作用是,这里将会初始化 BeanFactory、加载 Bean、注册 Bean 等等。(Bean 并没有实现初始化)

点进去obtainFreshBeanFactory()办法咱们一探到底。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {   // 敞开旧的 BeanFactory (如果有),创立新的 BeanFactory,加载 Bean 定义、注册 Bean 等等   refreshBeanFactory();   // 返回刚刚创立的 BeanFactory   ConfigurableListableBeanFactory beanFactory = getBeanFactory();   if (logger.isDebugEnabled()) {      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);   }   return beanFactory;}

refreshBeanFactory()应该是这个办法的重头戏,咱们再深刻进去。

@Overrideprotected final void refreshBeanFactory() throws BeansException {   // 如果 ApplicationContext 中曾经加载过 BeanFactory 了,销毁所有 Bean,敞开 BeanFactory   // 留神,利用中 BeanFactory 原本就是能够多个的,这里可不是说利用全局是否有 BeanFactory,而是以后ApplicationContext 是否有 BeanFactory   if (hasBeanFactory()) {      destroyBeans();      closeBeanFactory();   }   try {      // 初始化一个 DefaultListableBeanFactory,为什么应用这个BeanFactory?因为这是最牛的 BeanFactory。      DefaultListableBeanFactory beanFactory = createBeanFactory();      // 用于 BeanFactory 的序列化      beanFactory.setSerializationId(getId());      // 设置 BeanFactory 的两个配置属性:是否容许 Bean 笼罩、是否容许循环援用      customizeBeanFactory(beanFactory);      // 加载 Bean 到 BeanFactory 中      loadBeanDefinitions(beanFactory);      synchronized (this.beanFactoryMonitor) {         this.beanFactory = beanFactory;      }   }   catch (IOException ex) {      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);   }}

简略提一句,DefaultListableBeanFactory为什么是最牛的BeanFactory看下这个继承图大略就明了。

  // 设置 BeanFactory 的两个配置属性:是否容许 Bean 笼罩、是否容许循环援用  customizeBeanFactory(beanFactory);

这个形式只是一个设置,设置是否容许循环依赖,至于什么是循环依赖呢?也就是 A-B-C之间他们相互依赖,spring有一套本人的机制去解决循环依赖,当前文章为进行剖析,这一步仅仅是配置是否容许循环依赖,读者分明就能够了。

   // 这个办法将依据配置,加载各个 Bean,而后放到 BeanFactory 中  loadBeanDefinitions(beanFactory);

通过下面一系列的步骤,一个beandefintion就造成,beandefintion就是咱们常说的bean,也就是一个对象的加强版。

接下来就须要把这个bean退出到beanfactory中了,这一步交给loadBeanDefinitions()办法去执行。

spring办法命名的确精妙,只看看办法名大略也晓得每个办法干了什么!

创立一个beanDefinitionReader(bean阅读器)去读取xml中的bean,尽管xml很少用了,然而用它来举例还是很经典的。

真正干活的是loadBeanDefinitions(beanDefinitionReader),往下走很漫长漫长,把咱们xml中的bean解析成BeanDefinition,并调用registerBeanDefinition()办法把它注册到注册核心,发送注册事件。

总结一下,到这里曾经初始化了 Bean 容器,<bean /> 配置也相应的转换为了一个个 BeanDefinition,而后注册了各个 BeanDefinition 到注册核心,并且发送了注册事件。

到此obtainFreshBeanFactory() 办法也就正式完结了。

spring的调用过程链路十分十分的长,一步步点进去没一会你就迷了,田同学认为比拟好的一个方法就是,先站在办法体外看这个办法干了什么,而后逐渐拆分进入到每一个办法中。

站在refresh()外看这两个办法,prepareRefresh()筹备一下刷新要做的事,obtainFreshBeanFactory()注册好bean并退出到beanfactory中。

好啦,明天的spring源码剖析就到这里了。