spring IOC bean的加载流程

概述

在前面的学习当中,我们了解了spring的资源加载策略,知道了spring如何将资源封装为Resource并且利用ResourceLoader加载Resource资源,然后解析Resource资源,将其装换为保存在spring内部的元数据BeanDefinition。前面做的所有工作都是在为IOC容器开始Bean的加载所做的准备。

在这里插入图片描述

IOC容器的作用如上图所示,它通过加载元数据,然后将其解析到容器内部。然后根据这些信息绑定整个系统的对象,最终 组装成一个可用的基于轻量级容器的应用系统。 要想真正得到一个完整的IOC容器,需要两步:1.容器的初始化阶段和bean的加载阶段,而现在我们学习的内容就是针对于第二个阶段。

在Bean的加载阶段开始的时候,加载Bean所需要的全部的信息已经进入到系统中了。当我们显式或者隐式地调用 BeanFactory#getBean(…) 方法的时候,就会开启Bean的加载过程。

实例代码如下:

		ResourceLoader resourceLoader = new DefaultResourceLoader();// <1>
		//ClassPathResource resource = new ClassPathResource("bean.xml");
		ClassPathResource resource = (ClassPathResource)resourceLoader.getResource("bean.xml");
		DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); // <2>
		XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); // <3>
		reader.loadBeanDefinitions(resource); // <4>

		Car car = (Car)factory.getBean("car");
		System.out.println(car);

为了便于梳理整个加载过程,其时序图如下:

在这里插入图片描述

这里的时序图只是bean加载过程当中我认为比较重要的方法,具体的看代码分析。

总体流程分析

getBean

当我们显式或者隐式掉一共getBean方法的时候,就会触发架子啊Bean阶段。

	@Override
	public Object getBean(String name) throws BeansException {
   
		//doGetBean接受4个方法参数:获取bean的名字,bean的类型
		//创建bean式要传递的参数,是否类型检查。
		return doGetBean(name, null, null, false);
	}

真正实现加载机制的是doGetBean方法

doGetBean

这个方法就是上面时序图的体现。代码如下:

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
   

		/**
		 * 通过name获取beanName,这里不使用name直接作为beanName有两个原因
		 * 1.name可能以&字符开头,表明调用者想获取FactoryBean本身,而不是FactoryBean实现类所创建的
		 * bean。在BeanFactory中,FactoryBean的实现类和其他的bean存储方式是一样的。区别在于名字上多了个&
		 * 所以要移除这个&
		 * 2.还是别名的问题,转换需要。
		 */
		//1.返回bean名称,剥离工厂使用前缀,如果那么是alias,就过去对应的映射的beanname
		//如果是FactoryBean,要去除它前面的那个&
		final String beanName = transformedBeanName(name);
		//创建一个空的bean
		Object bean;
		// Eagerly check singleton cache for manually registered singletons.
		//如果这里是我们的bean,那么第一次获取肯定是空的,那么这个时候就会走else
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
   
			if (logger.isDebugEnabled()) {
   
				if (isSingletonCurrentlyInCreation(beanName)) {
   
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
   
					logger.debug("Returning cached instance of singleton bean '" + beanName + 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值