spring源码学习 - 配置文件bean的初始化

为什么开始看spring的源码
  • 半路转行写代码快一年半了,从开始工作就在使用spring框架,虽然会用,会搭框架,但是很多时候不懂背后的原理,比如:spring是怎样控制事务的,springmvc是怎样处理请求的,aop是如何实现的…这让人感觉非常不踏实,那就开始慢慢边看书边研究spring的源码吧!!!
怎样高效的看源码
  • 我的答案是带着具体的问题去看源码,不然非常容易陷入源码细节中不能自拔,然后就晕了,最后你发现这看了半天看的是啥玩意啊.
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定义
    <bean id="testBean" class="com.hunt.debug.TestBean">
        <property name="name" value="spring"/>
    </bean>
  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. 这里内部真正调用的是第二个构造器
    XmlBeanFactory类结构图

  3. 初始化入口:this.reader.loadBeanDefinitions(resource);
  4. 实际上是private final XmlBeanDefinitionReader reader这个对象负责spring容器的初始化,包括:xml配置文件载入,验证,解析,bean的注册
    XmlBeanDefinitionReader类结构图
  5. 继续进入loadBeanDefinitions(Resource resource)
  6. 进入到的是XmlBeanDefinitionReader中的loadBeanDefinitions(EncodedResource encodedResource):
    Paste_Image.png
  7. 继续进入XmlBeanDefinitionReader中的doLoadBeanDefinitions(InputSource inputSource, Resource resource)`:
    Paste_Image.png
  8. 继续进入XmlBeanDefinitionReader中的registerBeanDefinitions(Document doc, Resource resource):
    Paste_Image.png
  9. 准备数据,进入registerBeanDefinitions(Document doc, XmlReaderContext readerContext):
    Paste_Image.png
  10. 开始进入解析流程doRegisterBeanDefinitions(Element root):
    Paste_Image.png
  11. 终于做好了所有的准备,按照命名空间类别进行解析…跟进parseBeanDefinitions(root, this.delegate);:
    Paste_Image.png
  12. 按照标签规则进行解析
    Paste_Image.png
  13. 组装BeanDefinitionHolder并在容器中进行注册
    Paste_Image.png
  14. 组装BeanDefinitionHolder过程
  15. 创建容器数据对象过程,设置数据对象的属性
    Paste_Image.png
  16. 来看下容器对象中的数据对象到底是什么样子的:
  17. 回到processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate),继续最后一步: 向容器中进行注册!!!
    Paste_Image.png
  18. 最后一步,向容器注册是在DefaultListableBeanFactory中的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)进行实现的

  19. 到这里完成了bean向容器的注册,我们可以看下beanDefinitionMap容器已经有了testBean,到这里我们定义的testBean整个初始化过程就结束了
    Paste_Image.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值