Spring DI1--整体流程

Spring DI 源码分析一共有五篇
Spring DI1–整体流程
Spring DI2–三级缓存获取Bean
Spring DI3–从父级BeanFactory中获取Bean
Spring DI4–创建Bean
Spring DI5–不同作用域对Bean的处理

基于Spring 5.2.6.RELEASE
由前篇Spring IOC 的第一篇的案例代码,只有Spring DI是从ApplicationContext.getBean()开始的

ApplicationContext的getBean()是继承自BeanFactory,由子类AbstractApplicationContext实现

获取Bean

//AbstractApplicationContext#getBean(java.lang.String)
public Object getBean(String name) throws BeansException {
	assertBeanFactoryActive();//检查容器是否活着
	return getBeanFactory().getBean(name);
}
//AbstractBeanFactory#getBean(java.lang.String)
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}
//org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

	//将传入的名称转换为Bean的名称,因为可能传入的是别名
	final String beanName = transformedBeanName(name);
	Object bean;

	//获取实例	spring的三级缓存
	Object sharedInstance = getSingleton(beanName);
	//容器创建的实例
	//缓存中已经有了初始化好的单例bean
	if (sharedInstance != null && args == null) {
		if (logger.isDebugEnabled()) {
			//正在创建Bean,允许提前暴露的Bean,还未初始化完成
			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 + "'");
			}
		}
		//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}
	//缓存中没有初始化好的单例bean
	else {
		//没有初始化的单例Bean,但是有正在创建的原型Bean,并且因为循环依赖创建失败了
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		//获取父级的BeanFactory
		BeanFactory parentBeanFactory = getParentBeanFactory();
		//当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			//获取指定BeanName的原始名称 真正的beanName 不是别名 如果这个名字带&,返回值业户带&
			String nameToLookup = originalBeanName(name);
			//从父级BeanFactory获取bean
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
		}

		//创建的Bean是否需要进行类型验证,上面传入的false,不需要
		if (!typeCheckOnly) {
			//标记Bean已经被创建
			markBeanAsCreated(beanName);
		}

		try {
			//根据指定BeanDefinition获取其父级的Beandefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			//获取当前Bean所有依赖Bean的名称
			String[] dependsOn = mbd.getDependsOn();
			//如果当前Bean有依赖Bean,注册所有依赖的bean(不止这个bean依赖的bean,还有这个bean依赖的bean依赖的bean),并且对所有依赖的bean进行注入
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					//注册依赖的bean
					registerDependentBean(dep, beanName);
					getBean(dep);
				}
			}

			//创建单例Bean的实例对象
			if (mbd.isSingleton()) {
				//获取Bean实例
				sharedInstance = getSingleton(beanName, () -> {
					try {
						//创建Bean实例对象
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						//销毁对象
						destroySingleton(beanName);
						throw ex;
					}
				});
				//获取Bean
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			//创建原型Bean实例对象
			else if (mbd.isPrototype()) {
				//原型Bean,每次创建一个新的对象
				Object prototypeInstance = null;
				try {
					//调用创建前的前置方法
					beforePrototypeCreation(beanName);
					//创建Bea
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					//调用创建后的后知方法
					afterPrototypeCreation(beanName);
				}
				//获取Bean
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			//要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
			//配置的Bean的作用域,选择实例化Bean的合适方法
			//例如web中的:request、session、application等作用域
			else {
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				//BeanDefinition中没有配置作用域
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					//获取bean实例
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);//调用前置方法
						try {//创建Bea
							return createBean(beanName, mbd, args);
						}
						finally {
							afterPrototypeCreation(beanName);//调用后置方法
						}
					});
					//获取Bean
					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
							"Scope '" + scopeName + "' is not active for the current thread; consider " +
							"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
							ex);
				}
			}
		}
		catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}

	//对Bean进行类型检查
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return convertedBean;
		}
		catch (TypeMismatchException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}

doGetBean() 主要有以下几步:

1、获取真正的beanName;

2、从三级缓存中去获得bean;

​ factoryBean的处理

3、从父BeanFactory中获取Beandefinition

​ 用父BeanFactory获取bean

4、获取BeanDefinition

​ 注入所有依赖的bean

​ 创建bean

​ 单例:

​ 创建单例bean

​ 将bean加入缓存

​ factoryBean的处理

​ Prototype:

​ 创建多例bean

​ factoryBean的处理

​ 其他Scope:

​ 从相应scope中获取bean并执行factorybean

5、对bean类型检查,返回bean

1、转换beanName

//转换bean名称	下面两个方法,在di中会经常用到  获取bean的真正beanName,如果是别名,通过别名缓存一层层查找
protected String transformedBeanName(String name) {
	return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

1.1、转换bean名称

private static final Map<String, String> transformedBeanNameCache = new ConcurrentHashMap<>();
//org.springframework.beans.factory.BeanFactoryUtils#transformedBeanName
public static String transformedBeanName(String name) {
    Assert.notNull(name, "'name' must not be null");
    if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
        return name;
    }
    return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
        do {
            beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
        }
        while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
        return beanName;
    });
}

这里判断传入的beanName是否以&符号(获取factorybean)开头,如果不是直接返回,如果是,获取&符号后面的名称,并将对应关系放入缓存中。

1.2、获取真正的名称

private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
//SimpleAliasRegistry#canonicalName
public String canonicalName(String name) {
	String canonicalName = name;
	String resolvedName;
	do {
		resolvedName = this.aliasMap.get(canonicalName);
		if (resolvedName != null) {
			canonicalName = resolvedName;
		}
	}
	while (resolvedName != null);
	return canonicalName;
}

这里传入的名称可能是别名,根据bean别名获取bean名称,会一层一层的查找,找到最终的bean名称

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值