spring源码学习 - xml方式bean的解析注册过程

为什么开始看spring的源码
  • 半路转行写代码快一年半了,从开始工作就在使用spring框架,虽然会用,会搭框架,但是很多时候不懂背后的原理,比如:spring是怎样控制事务的,springmvc是怎样处理请求的,aop是如何实现的...这让人感觉非常不踏实,那就开始慢慢边看书边研究spring的源码吧!!!
怎样高效的看源码
  • 我的答案是带着具体的问题去看源码,不然非常容易陷入源码细节中不能自拔,然后就晕了,最后你发现这看了半天看的是啥玩意啊.
spring容器核心类结构图,方便我们理清思路,主要参考自书籍<>
spring源码学习 - xml方式bean的解析注册过程_第1张图片
spring容器核心类结构图
下面正式开始源码bug
  1. 创建一个简单的javaBean. 下面debug过程尽量只针对该bean的初始化过程进行跟踪,以免陷入源码细节出不来...
public class TestBean {
  private String name;

  public TestBean() {
  }

  public TestBean(String name) {
      this.name = name;
  }

  public String getName() {
      return name;
  }

  public void setName(String name) {
      this.name = name;
  }
}
  1. spring.xml定义
    
        
    
  1. 利用spring集成单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration(value = "classpath:src/main/webapp")
@ContextConfiguration({"classpath:spring.xml", "classpath:spring/spring-mvc.xml"})
@Transactional
public class DebugSpring {
    private static final Logger log = LoggerFactory.getLogger(DebugSpring.class);
    @Test
    public void testLoad() throws IOException {
        Resource resource = new ClassPathResource("spring.xml");
        BeanFactory xmlBeanFactory = new XmlBeanFactory(resource);
        TestBean testBean = xmlBeanFactory.getBean("testBean", TestBean.class);
        log.debug("test bean name is :{}", testBean.getName());
    }
}
  1. 开始debug

  2. 这里内部真正调用的是第二个构造器


    spring源码学习 - xml方式bean的解析注册过程_第2张图片
    XmlBeanFactory类结构图
  3. 初始化入口:this.reader.loadBeanDefinitions(resource);

  4. 实际上是private final XmlBeanDefinitionReader reader这个对象负责spring容器的初始化,包括:xml配置文件载入,验证,解析,bean的注册

    spring源码学习 - xml方式bean的解析注册过程_第3张图片
    XmlBeanDefinitionReader类结构图

  5. 继续进入loadBeanDefinitions(Resource resource)

  6. 进入到的是XmlBeanDefinitionReader中的loadBeanDefinitions(EncodedResource encodedResource):

    spring源码学习 - xml方式bean的解析注册过程_第4张图片
    Paste_Image.png

  7. 继续进入XmlBeanDefinitionReader中的doLoadBeanDefinitions(InputSource inputSource, Resource resource)`:

    spring源码学习 - xml方式bean的解析注册过程_第5张图片
    Paste_Image.png

  8. 继续进入XmlBeanDefinitionReader中的registerBeanDefinitions(Document doc, Resource resource):

    Paste_Image.png

  9. 准备数据,进入registerBeanDefinitions(Document doc, XmlReaderContext readerContext):

    spring源码学习 - xml方式bean的解析注册过程_第6张图片
    Paste_Image.png

  10. 开始进入解析流程doRegisterBeanDefinitions(Element root):

    spring源码学习 - xml方式bean的解析注册过程_第7张图片
    Paste_Image.png

  11. 终于做好了所有的准备,按照命名空间类别进行解析,解析规则是如果是则按照默认方式否则按照自定义解析方式...跟进parseBeanDefinitions(root, this.delegate);:

    spring源码学习 - xml方式bean的解析注册过程_第8张图片
    Paste_Image.png

    spring源码学习 - xml方式bean的解析注册过程_第9张图片
    Paste_Image.png

  12. 按照标签规则进行解析


    spring源码学习 - xml方式bean的解析注册过程_第10张图片
    Paste_Image.png
  13. 组装BeanDefinitionHolder并在容器中进行注册 ,为什么需要对容器对象进行包装呢,因为容器对容器和别名是分两个属性进行维护的.

    spring源码学习 - xml方式bean的解析注册过程_第11张图片
    Paste_Image.png

  14. 组装BeanDefinitionHolder过程

    spring源码学习 - xml方式bean的解析注册过程_第12张图片

  15. 创建容器数据对象过程,设置数据对象的属性


    spring源码学习 - xml方式bean的解析注册过程_第13张图片
    Paste_Image.png
  16. 来看下容器对象中的数据对象到底是什么样子的:


    spring源码学习 - xml方式bean的解析注册过程_第14张图片
  17. 回到processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate),继续最后一步: 向容器中进行注册!!!

    spring源码学习 - xml方式bean的解析注册过程_第15张图片
    Paste_Image.png

  18. 最后一步,向容器注册是在DefaultListableBeanFactory中的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)进行实现的

    spring源码学习 - xml方式bean的解析注册过程_第16张图片

    spring源码学习 - xml方式bean的解析注册过程_第17张图片

  19. 到这里完成了bean向容器的注册,我们可以看下beanDefinitionMap容器已经有了testBean,到这里我们定义的testBean整个初始化过程就结束了

    spring源码学习 - xml方式bean的解析注册过程_第18张图片
    Paste_Image.png

参考资料
  • Spring深度源码分析

你可能感兴趣的:(spring源码学习 - xml方式bean的解析注册过程)