【spring】获取Bean的方法:getBean源码分析

getBean简单介绍

  • 本文源码基于spring-framework-5.3.10。
  • spring启动的时候会创建非懒加载的单例Bean。
  • 通过BeanFactory或者实现BeanFactory的子类(ApplicationContext)进行调用。

@DependsOn注解介绍

  • 通知spring在创建当前Bean的时候,先去创建@DependsOn注解中配置的Bean。

源码流程

  • 调用doGetBean方法
  • 获取BeanName(transformedBeanName方法):获取FactoryBean的getObject方法中的值,name传值的前面需要加一个&符号。一个Bean有多个名字(别名),要获取到这个别名对应主要的BeanName。
  • FactoryBean直接走getObject的逻辑,普通Bean开始创建获取。
  • 普通Bean有父BeanFactory,直接调用父BeanFactory的getBean
  • 普通Bean检查是不是抽象bean,抽象Bean抛异常。
  • 普通Bean去创建@DependsOn注解中配置的Bean。
  • 根据不同的Scope去获取Bean。
  • 校验类型是否匹配。

源码重点关注内容

  • FactoryBean和普通Bean的区别
  • @DependsOn优先加载Bean的逻辑
  • 不同Scope加载Bean的逻辑:进阶可以理解mvc中request作用域与session作用域的实现方式。

getBean方法源码分析

// 4个方法全部调用doGetBean方法
/**
 * 参数是Bean的名字
 */
@Override
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

/**
 * 参数是Bean的名字和Bean的类型
 */
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
	return doGetBean(name, requiredType, null, false);
}

/**
 * 参数是Bean的名字和Bean构造方法的参数
 */
@Override
public Object getBean(String name, Object... args) throws BeansException {
	return doGetBean(name, null, args, false);
}
/**
 * 参数是Bean的名字和Bean的类型和Bean构造方法的参数
 */
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
		throws BeansException {
	return doGetBean(name, requiredType, args, false);
}

getBean的核心:doGetBean源码分析

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

	// FactoryBean的逻辑:name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx
	// 别名逻辑:name有可能传入进来的是别名,那么beanName就是id
	String beanName = transformedBeanName(name);
	Object beanInstance;

	// Eagerly check singleton cache for manually registered singletons.
	// 直接从单例池去获取Bean
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		// 拿到单例Bean,并且是无参的时候,执行下面的逻辑
		// 这里就是打印日志
		if (logger.isTraceEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		// 如果是FactoryBean,那么就调用getObject()返回对象
		beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		// 循环依赖的时候使用:记录当前的Bean正在创建
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// Check if bean definition exists in this factory.
		// 获取父BeanFactory
		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 存在父BeanFactory,并且当前beanDefinitionMap中没有这个Bean
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			// 名字的转换:&&&&xxx---->&xxx
			String nameToLookup = originalBeanName(name);
			// 使用不同的参数去调用父BeanFactory的方法
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		// 循环依赖的时候使用:把Bean标记为已创建
		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		// JFR时间记录开始位置
		StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
				.tag("beanName", name);
		try {
			// JFR的标签
			if (requiredType != null) {
				beanCreation.tag("beanType", requiredType::toString);
			}
			// 拿到合并之后的BeanDefinition
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

			// 检查BeanDefinition是不是Abstract的,抽象的会抛异常!
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			// 得到@DependsOn注解中配置的值:加载当前Bean需要的前置Bean
			String[] dependsOn = mbd.getDependsOn();
			// 这个判断说明配置类@DependsOn注解
			if (dependsOn != null) {
				// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了
				for (String dep : dependsOn) {
					// beanName是不是被dep依赖了,如果是则出现了循环依赖
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value。方便其他Bean进行上门的判断
					registerDependentBean(dep, beanName);

					// 创建所依赖的bean
					try {
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// Create bean instance.
			// 单例Bean的创建逻辑
			if (mbd.isSingleton()) {
				// 创建单例Bean,并添加到单例池
				sharedInstance = getSingleton(beanName, () -> {
					try {
						// 真正的创建一个Bean
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						// Explicitly remove instance from singleton cache: It might have been put there
						// eagerly by the creation process, to allow for circular reference resolution.
						// Also remove any beans that received a temporary reference to the bean.
						// 有问题销毁当前的单例Bean
						destroySingleton(beanName);
						throw ex;
					}
				});
				// 如果是FactoryBean,那么就调用getObject()返回对象
				beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}
			// 原型Bean的创建逻辑
			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					// 创建Bean的前置逻辑:标记Bean正在创建
					beforePrototypeCreation(beanName);
					// 真正的创建一个Bean
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					// 创建Bean的后置逻辑:标记Bean完成创建
					afterPrototypeCreation(beanName);
				}
				// 如果是FactoryBean,那么就调用getObject()返回对象
				beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
			else {
				// 这里是其他的作用域:比如说mvc里面的request,session作用域
				// 得到当前BeanDefinition的scope属性
				String scopeName = mbd.getScope();
				// 没有值,抛异常
				if (!StringUtils.hasLength(scopeName)) {
					throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
				}
				// 得到当前名字对应的具体Scope
				Scope scope = this.scopes.get(scopeName);
				// Scope不存在的时候抛异常
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					// 类似单例,放到他自己的作用域:单例放在单例池。request需要保证这个对象中获取的是同一个Bean。缓存到一个变量。
					// session.getAttriute(beaName):缓存在session的一个变量中
					// request.getAttriute(beaName):缓存在request的一个变量中
					Object scopedInstance = scope.get(beanName, () -> {
						// 创建Bean的前置逻辑:标记Bean正在创建
						beforePrototypeCreation(beanName);
						try {
							// 真正的创建一个Bean
							return createBean(beanName, mbd, args);
						}
						finally {
							// 创建Bean的后置逻辑:标记Bean完成创建
							afterPrototypeCreation(beanName);
						}
					});
					// 如果是FactoryBean,那么就调用getObject()返回对象
					beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new ScopeNotActiveException(beanName, scopeName, ex);
				}
			}
		}
		catch (BeansException ex) {
			beanCreation.tag("exception", ex.getClass().toString());
			beanCreation.tag("message", String.valueOf(ex.getMessage()));
			// 当前的Bean从alreadyCreated删除调用
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
		finally {
			// JFR时间记录开始位置
			beanCreation.end();
		}
	}

	// 传入的类型判断:检查通过name所获得到的beanInstance的类型是否是requiredType
	return adaptBeanInstance(name, beanInstance, requiredType);
}

转化为主要的BeanName的方法:transformedBeanName源码分析

/**
 * 转化BeanName
 */
protected String transformedBeanName(String name) {
	return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

/**
 * FactoryBean的逻辑:name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx
 */
public static String transformedBeanName(String name) {
	// BeanName为空抛异常
	Assert.notNull(name, "'name' must not be null");
	// 不是&开头,直接返回名字
	if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
		return name;
	}
	// 以&开头,FactoryBean:获取去掉&的名字
	return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
		// 这是是个循环,一直到开头不是&。所以说写一个&和多个&&&&&是没有区别的,都会干掉
		do {
			// 去掉&符号
			beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
		}
		while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
		// 返回去掉&符号的名称
		return beanName;
	});
}

/**
 * 别名逻辑:name有可能传入进来的是别名,那么beanName就是id
 */
public String canonicalName(String name) {
	// 赋值当前Name
	String canonicalName = name;
	// Handle aliasing...
	// 处理别名
	String resolvedName;
	// aliasMap的结构是{别名:真实名字,别名:真实名字},一直找到这个Map中没有
	do {
		resolvedName = this.aliasMap.get(canonicalName);
		if (resolvedName != null) {
			canonicalName = resolvedName;
		}
	}
	while (resolvedName != null);
	// 返回真实的BeanName
	return canonicalName;
}

判断类型匹配的逻辑

<T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
	// Check if required type matches the type of the actual bean instance.
	// 类型不满足的时候,进行下面的逻辑
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			// 类型转化成功的时候,才会返回Bean,否则抛异常
			Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return (T) convertedBean;
		}
		catch (TypeMismatchException ex) {
			if (logger.isTraceEnabled()) {
				logger.trace("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	// 类型满足,直接返回Bean
	return (T) bean;
}

获取单例Bean的方法getSingleton源码分析

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	// beanName为空,抛异常
	Assert.notNull(beanName, "Bean name must not be null");
	synchronized (this.singletonObjects) {
		// 从单例池获取
		Object singletonObject = this.singletonObjects.get(beanName);

		if (singletonObject == null) {
			// 没有获取到的逻辑
			// Bean被销毁,抛异常
			if (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName,
						"Singleton bean creation not allowed while singletons of this factory are in destruction " +
						"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
			}
			// 日志打印
			if (logger.isDebugEnabled()) {
				logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}
			// 循环依赖一级缓存中移除
			beforeSingletonCreation(beanName);
			// 新的单例的标志为False
			boolean newSingleton = false;
			// 获取排除标志
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			// 排除标志为null的时候,设置这个标志不为null:标明执行开始了
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				// 调用上面的lambda去真正的创建Bean
				singletonObject = singletonFactory.getObject();
				// 创建Bean成功
				newSingleton = true;
			}
			catch (IllegalStateException ex) {
				// Has the singleton object implicitly appeared in the meantime ->
				// if yes, proceed with it since the exception indicates that state.
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					throw ex;
				}
			}
			catch (BeanCreationException ex) {
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
					}
				}
				throw ex;
			}
			finally {
				// 将排除的标志变为null:标明执行完成了
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				// 循环依赖一级缓存中放入
				afterSingletonCreation(beanName);
			}

			// 添加到单例池
			if (newSingleton) {

				addSingleton(beanName, singletonObject);
			}
		}
		// 返回得到的单例Bean
		return singletonObject;
	}
}

结束语

  • 获取更多本文的前置知识文章,以及新的有价值的文章,让我们一起成为架构师!
  • 关注公众号,可以让你对MySQL、并发编程、spring源码有深入的了解!
  • 关注公众号,后续持续高效的学习JVM!
  • 这个公众号,无广告!!!每日更新!!!
    作者公众号.jpg
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值