spring学习(四)——Bean的加载(不从缓存中获取bean)

 

参考文章:

http://www.iocoder.cn

假如spring未从缓存中获得bean的话,执行的业务逻辑

//缓存中不存在
		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			//因为 Spring 只解决单例模式下得循环依赖,在原型模式下如果存在循环依赖则会抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			//如果容器中没有找到,则从父类容器中加载
			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
                // 获得原始的类名
				String nameToLookup = originalBeanName(name);
				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);
			}

			try {
				//从容器中获取 beanName 相应的 GenericBeanDefinition 对象,并将其转换为 RootBeanDefinition 对象
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				//检查并且合并bean
				checkMergedBeanDefinition(mbd, beanName, args);

				//处理所依赖的 bean
				// Guarantee initialization of beans that the current bean depends on.
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						// 若给定的依赖 bean 已经注册为依赖给定的 bean
						// 循环依赖的情况
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						// 缓存依赖调用
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}
				// bean 实例化
				// Create bean instance.
				if (mbd.isSingleton()) {
					//单例模式
					sharedInstance = getSingleton(beanName, () -> {
						try {
							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;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				// 原型模式
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				// 从指定的 scope 下创建 bean
				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						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;
			}
		}

内容非常长,大概的逻辑为

可以看到里面主要的方法为:

  • #isPrototypeCurrentlyInCreation(String beanName) 方法,判断当前 Bean 是否正在创建
  • #containsBeanDefinition(String beanName) 方法中不存在 beanName 相对应的 BeanDefinition 对象时
  • #doGet 使用父类的方法来获得bean
  • #getMergedLocalBeanDefinition(String beanName) 方法,获取相对应的 BeanDefinition 对象
  • #checkMergedBeanDefinition() 方法,检查给定的合并的 BeanDefinition 对象
  • #处理依赖 方法,实例化依赖的 Bean 对象
  • #isDependent(String beanName, String dependentBeanName) 方法,是校验该依赖是否已经注册给当前 Bean
  • #registerDependentBean(String beanName, String dependentBeanName) 方法,将该依赖进行注册,便于在销毁 Bean 之前对其进行销毁
  • #getBean(String beanName) 方法,实例化依赖 Bean 对象

下面开始看这些方法内容

isPrototypeCurrentlyInCreation

判断当前 Bean 是否正在创建

/**
	 * Return whether the specified prototype bean is currently in creation
	 * (within the current thread).
	 * 首先检查该 beanName 是否处于原型模式下且正在创建中
	 * @param beanName the name of the bean
	 */
	protected boolean isPrototypeCurrentlyInCreation(String beanName) {
		//其实检测逻辑和单例模式一样,一个“集合”存放着正在创建的 Bean ,
		//从该集合中进行判断即可,只不过单例模式的“集合”为 Set ,而原型模式的则是 ThreadLocal
		Object curVal = this.prototypesCurrentlyInCreation.get();
		return (curVal != null &&
				(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
	}

 

#containsBeanDefinition(String beanName) 

方法中不存在 beanName 相对应的 BeanDefinition 对象时

public boolean containsBeanDefinition(String beanName) {
		Assert.notNull(beanName, "Bean name must not be null");
		return this.beanDefinitionMap.containsKey(beanName);
	}

#doGet /doGetBean方法

使用父类方法获得bean

if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				// 获得原始的类名
				String nameToLookup = originalBeanName(name);
				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);
				}
			}

#getMergedLocalBeanDefinition(String beanName) 方法

获取相对应的 BeanDefinition 对象

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// Quick check on the concurrent map first, with minimal locking.
		// 快速从缓存中获取,如果不为空,则直接返回
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		if (mbd != null) {
			return mbd;
		}
		// 获取 RootBeanDefinition,
		// 如果返回的 BeanDefinition 是子类 bean 的话,则合并父类相关属性
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}

#checkMergedBeanDefinition() 方法

检查给定的合并的 BeanDefinition 对象‘

protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
			throws BeanDefinitionStoreException {
		//
		if (mbd.isAbstract()) {
			throw new BeanIsAbstractException(beanName);
		}
	}

处理依赖 方法

实例化依赖的 Bean 对象

            String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						// 若给定的依赖 bean 已经注册为依赖给定的 bean
						// 循环依赖的情况
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						// 缓存依赖调用
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

#isDependent(String beanName, String dependentBeanName) 方法

是校验该依赖是否已经注册给当前 Bean

protected boolean isDependent(String beanName, String dependentBeanName) {
		synchronized (this.dependentBeanMap) {
			return isDependent(beanName, dependentBeanName, null);
		}
	}

	private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
		// alreadySeen 已经检测的依赖 bean
		if (alreadySeen != null && alreadySeen.contains(beanName)) {
			return false;
		}
		// 获取原始 beanName
		String canonicalName = canonicalName(beanName);
		// 获取当前 beanName 的依赖集合
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		if (dependentBeans == null) {
			return false;
		}
		// 存在,则证明存在已经注册的依赖
		if (dependentBeans.contains(dependentBeanName)) {
			return true;
		}
		// 递归检测依赖
		for (String transitiveDependency : dependentBeans) {
			if (alreadySeen == null) {
				alreadySeen = new HashSet<>();
			}
			// 添加alreadySeen中
			alreadySeen.add(beanName);
			// 递归
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
				return true;
			}
		}
		return false;
	}

//对象保存的是依赖 beanName 之间的映射关系:beanName - > 依赖 beanName 的集合
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

#registerDependentBean(String beanName, String dependentBeanName) 方法

将该依赖进行注册,便于在销毁 Bean 之前对其进行销毁

public void registerDependentBean(String beanName, String dependentBeanName) {
		String canonicalName = canonicalName(beanName);

		// 添加 <canonicalName, <dependentBeanName>> 到 dependentBeanMap 中
		synchronized (this.dependentBeanMap) {
			Set<String> dependentBeans =
					this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
			if (!dependentBeans.add(dependentBeanName)) {
				return;
			}
		}
		// 添加 <dependentBeanName, <canonicalName>> 到 dependenciesForBeanMap 中
		synchronized (this.dependenciesForBeanMap) {
			Set<String> dependenciesForBean =
					this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
			dependenciesForBean.add(canonicalName);
		}
	}


/** Map between dependent bean names: bean name to Set of dependent bean names. */
	/**
	 * 保存的是依赖 beanName 之间的映射关系:beanName - > 依赖 beanName 的集合
	 */
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

	/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
	/**
	 * 保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
	 */
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

#getBean(String beanName) 方法

实例化依赖 Bean 对象

然后使用getBean获得类

public Object getBean(String name) throws BeansException {
		return doGetBean(name, //要获取 Bean 的名字
				null, //要获取 bean 的类型
				null, //创建 Bean 时传递的参数。这个参数仅限于创建 Bean 时使用
				false);//是否为类型检查
	}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring框架Bean缓存是通过三级缓存实现的。其缓存就是指单例Bean缓存。 当我们首次通过Spring容器获取一个单例Bean时,Spring会先从一级缓存查找是否已经存在该Bean的实例。如果存在,则直接返回该实例;如果不存在,则继续执行后续步骤。 在后续的步骤Spring会尝试从二级缓存获取Bean的实例。二级缓存是一个用于存储原始的Bean定义信息的缓存,它是为了解决循环依赖问题而存在的。如果二级缓存存在Bean的定义信息,则Spring会根据这些信息创建一个新的Bean实例,并放入一级缓存,然后返回该实例。 如果二级缓存不存在Bean的定义信息,或者在创建Bean实例时出现了循环依赖问题,那么Spring会继续执行后续步骤。 在后续步骤Spring会尝试从三级缓存获取Bean的实例。三级缓存是一个用于存储已经创建但是尚未初始化完成的Bean实例的缓存。如果三级缓存存在Bean的实例,则Spring会使用这个实例,并将其放入一级缓存,然后返回该实例。 如果三级缓存不存在Bean的实例,或者在初始化Bean实例时出现了异常,那么Spring会继续执行后续步骤。 在后续步骤Spring会根据Bean的定义信息创建一个新的实例,并将其放入一级缓存,然后返回该实例。 总结一下,一级缓存就是用于缓存单例Bean实例的,它是SpringBean缓存机制的第一层。一级缓存的存在可以提高Bean获取效率,避免重复创建实例。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大·风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值