栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Spring源码】3. xml文件如何转换成BeanDefinition(图解向,堆图预警)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring源码】3. xml文件如何转换成BeanDefinition(图解向,堆图预警)

一堆图预警~~~

通过测试启动类进入ApplicationContext容器

设置(解析)配置文件路径

setConfigLocations(configLocations);

  • 参数configLocations格式是String[]

​进入超级重要的refresh()方法

1.准备工作:prepareRefresh()

protected void prepareRefresh() {
   // Switch to active.
   
   this.startupDate = System.currentTimeMillis();
   
   this.closed.set(false);
   
   this.active.set(true);

   
   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
   
   getEnvironment().validateRequiredProperties();


   
   // Store pre-refresh 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<>();
}
2.创建工厂:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

先创建一个工厂,创建的工厂的名字是 DefaultListableBeanFactory

refreshBeanFactory()

​自定义风格化的customizeBeanFactory(beanFactory);

这两个属性默认都是true(父类构造时赋的值)

​超级重要的loadBeanDefinitions(beanFactory)

点进方法看到啥都木有,同学不要慌~~点下面就可以看到他的实现子类啦。。。

​由上图可以发现,在Spring中这个方法有四个实现,选择进入哪个取决于你使用的配置方式:

  • AbstractXmlApplicationContext (org.springframework.context.support)

    • 使用的是xml配置bean的选这个

    • 位于spring.spring-context.main

  • AnnotationConfigWebApplicationContext (org.springframework.web.context.support)

    • spring.spring-web.main

  • GroovyWebApplicationContext (org.springframework.web.context.support)

    • spring.spring-web.main

  • XmlWebApplicationContext (org.springframework.web.context.support)

    • spring.spring-web main

由于本文是以xml配置文件为示例,故我们选择AbstractXmlApplicationContext这个类里的

loadBeanDefinitions(beanDefinitionReader)的实现

​再次进入名为loadBeanDefinitions(beanDefinitionReader) 的方法中

​再再次进入名为loadBeanDefinitions(configLocations) 的方法中

​再再再次进入名为loadBeanDefinitions(location)的方法中

​再再再再次进入名为loadBeanDefinitions(resources) 的方法中

​再再再再再次进入名为loadBeanDefinitions(resources) 的方法中

进入其实现子类

​选择类XmlBeanDefinitionReader

再再再再再再次进入名为loadBeanDefinitions(resources) 的方法中

​doLoadBeanDefinitions(inputSource, encodedResource.getResource());

​再次进入名为doLoadBeanDefinitions(inputSource, encodedResource.getResource())的方法中

​doLoadDocument(InputSource inputSource, Resource resource)

getValidationModeForResource(Resource resourc)

​detectValidationMode(Resource resource)

​detectValidationMode(InputStream inputStream)

​loadDocument()

​先总结下配置参数configLocations的类型转换的过程:

String[] ---> String ---> Resource[] ---> Resource ---> document文档 ---> 根据文档的节点信息封装成一个个的BeanDefinition

继续!~

registerBeanDefinitions(doc, resource);

​createBeanDefinitionDocumentReader()

​registerBeanDefinitions(doc, createReaderContext(resource));

doRegisterBeanDefinitions(Element root) ;

​我们转换的是BeanDefinition,所以进入了BEAN_ELEMENT这个条件分支中

​选择子类DefaultListableBeanFactory

​下面两张图是一个函数(这个函数有点长~)

​走到这里,我们见证了BeanDefinition和BeanName都被放进了相应的容器内!

this.beanDefinitionMap.put(beanName, beanDefinition);

this.beanDefinitionNames.add(beanName);

这篇就先到这了喽~下篇继续 >>> 努力脸.gif

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/848096.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号