Spring创建Bean 中的三级缓存 解决循环依赖

Spring创建Bean 中的三级缓存 解决循环依赖

Bean 创建的简单介绍
Spring 创建的主要流程在 AbstractApplicationContext.refresh

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 一些准备工作,读取一些配置变量,设置启动标识等
			prepareRefresh();

			// 创建BeanFactory 并将BeanDefinition 放入对应的Map 中
			// 方法最终会调用 AbstractRefreshableApplicationContext.refreshBeanFactory 
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 设置BeanFactory 的类加载器 , 设置几个特殊的BeanPostProcessor
			// BeanPostProcessor 用于加入到Bean 的生命周期,初始化前postProcessBeforeInitialization
			//初始化后执行 postProcessAfterInitialization 可以用于创建Bean 改变Bean 属性
			//这里也会有ApplicationListenerDetector (BeanPostProcessor)用于注册监听器
			prepareBeanFactory(beanFactory);

			try {
				// 留给子类的扩展点,可以在这里添加BeanPostProcessor和BeanFactoryPostProcessor 
				// BeanFactoryPostProcessor 可以对beanFactory进行相关操作
				postProcessBeanFactory(beanFactory);

				// 调用 BeanFactoryPostProcessor 实现类的 postProcessBeanFactory(factory)方法
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册 BeanPostProcessor 的实现类,Bean 还没有初始化
				registerBeanPostProcessors(beanFactory);

				// 国际化相关操作
				initMessageSource();

				// 初始化 ApplicationContext 的事件广播器,对ApplicationListener 的处理,这个会在后面的registerListeners()进行添加
				initApplicationEventMulticaster();

				// 模板方法 留给子类扩展
				onRefresh();

				//注册ApplicationListener 事件监听器
				registerListeners();

				//初始化所有的 singleton beans (lazy-init 的除外)
				finishBeanFactoryInitialization(beanFactory);

				//  最后,广播事件ApplicationContext 初始化完成,并做一些清理操作等
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				//  销魂Bean
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

一些方法说明
invokeBeanFactoryPostProcessors:会创建和调用BeanFactoryPostProcessor 的相关方法
registerBeanPostProcessors:会注册创建所有的BeanPostProcessor ,这里我们普通用到的Bean 是还没有创建生成的。
invokeBeanFactoryPostProcessors和registerBeanPostProcessors中 普通的bean都是没有创建的,所以不要在这里使用getBean 和自动注入,因为这样你可能会打乱Spring的流程造成Bean的创建异常
finishBeanFactoryInitialization:开始创建普通的Bean 不包括懒加载的bean


AbstractApplicationContext.finishBeanFactoryInitialization 中主要的步骤在DefaultListableBeanFactory.preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}
		//获取所有的定义的Bean的名字
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			// 这个对BeanDefinition 进行合并 ,合并parent(设置的,不是类中的继承关系,xml 中用parent 定义的)<bean id="" class="" parent="" />
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);//通过getBean 触发bean的初始化
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

		// 对所有继承了SmartInitializingSingleton bean 的进行回调处理
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

这个方法中比较重要的方法是getBean,最后是一直调用到AbstractBeanFactory.doGetBean


	
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
	 	// 将别名转成通用的beanName ,这步主要的目的是确定通用的beanName 
		String beanName = transformedBeanName(name);
		//这个是返回值 
		Object bean;

		// 查询创建的缓存中是否已经存在这个bean,这里有三级缓存,用于解决循环引用的问题
		//里面有三个缓存,后面把代码贴出来
		//Map<String, Object> singletonObjects 最终的bean 完全创建初始化完那种
		//Map<String, ObjectFactory<?>> singletonFactories 存放创建bean的工厂,bean未被创建
		//Map<String, Object> earlySingletonObjects 早期暴露单未被初始化完的bean,比如依赖注入未完成之类的,一般从singletonFactories 来
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			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 的话,返回它创建的那个实例对象,name 如果是&开头返回FactoryBean 实例
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
			// 创建过了此 beanName 的 prototype 类型的 bean,那么抛异常,一般是循环引用造成
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//当前容器中不存在相关的bean 的定义 检查parentBeanFactory(父亲容器)
			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);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}
			// 到这里准备开始创建Bean 了,之前都没有创建
			try {
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// 注意这里DependsOn 是指<bean depends-on =""/>,这个一般用不到,不是分析重点
				String[] dependsOn = mbd.getDependsOn();
				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 + "'");
						}
						//注册依赖
						registerDependentBean(dep, beanName);
						try {
							// 先初始化被依赖项
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				if (mbd.isSingleton()) {
					//单例创建,getSingleton 总体逻辑就是执行createBean ,创建完之后会调用DefaultSingletonBeanRegistry.addSingleton(beanName, singletonObject);用于同步一下三级缓存的状态,主体逻辑就是放进singletonObjects (一级缓存)中,清楚其他缓存中这个beanName 的相关信息
					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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					//Prototype 的创建
					// 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);
				}

				else {
					// 不是 Prototype 和 singleton 的创建
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					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;
			}
		}

		//最后检查一下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.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

三级缓存的主要代码

/** Cache of singleton objects: bean name to bean instance. */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** Cache of singleton factories: bean name to ObjectFactory. */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** Cache of early singleton objects: bean name to bean instance. */
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

不管哪种方式创建都会调用AbstractAutowireCapableBeanFactory.createBean,所以看看createBean

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		// 确保 BeanDefinition 中的 Class 被加载
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		//spring 中的一个功能,通过配置replaced-method 和实现org.springframework.beans.factory.support.MethodReplacer 可以替换目标类的方法,这个不是我们的重点,略过
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			// 执行实现了InstantiationAwareBeanPostProcessor 的类的相关方法postProcessBeforeInstantiation,这个是返回代理类的地方,也是Spring中返回aop 代理的地方
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			// 创建 bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

/** Cache of unfinished FactoryBean instances: FactoryBean name to BeanWrapper. */
	private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			//查看ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache 是否存在
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
		    //这里实例化 Bean,里面分情况看是否需不需要自动注入的构造方法创建对象,一般都是无参构造创建,所以略过
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		// 这个就是我们定义的bean 的实例
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		//MergedBeanDefinitionPostProcessor 的回调 允许改变beandefinition,这里有用于实现@Autowired和@Value 功能的AnnotationInjectedBeanPostProcessor, 扫描类中关于@Autowired和@Value的定义,并将其封装成对应的数据类InjectionMetadata保存进beandefinition 中,用于实现自动注入
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		//是否可以提前暴露引用=是否单例,容器是否允许循环引用出现(默认可以),是否当前创建的bean
		// 这里提前暴露未完全初始化完的bean实例 是为了解决循环引用的问题
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			// 添加到三级缓存中,用于解决循环引用,getEarlyBeanReference 会回调SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference 这个方法用于拿到早期暴露的需要被aop 代理的代理类的对象,这样就不会导致循环引用的是原始对象
			// () -> getEarlyBeanReference(beanName, mbd, bean) 这个是ObjectFactory 的实现类,没有马上运行getEarlyBeanReference ,后面才运行的,结合之前的doGetBean 中的Object singletonInstance = getSingleton(beanName); 解决循环引用
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		// 这个就是我们之前创建的bean实例 
		Object exposedObject = bean;
		try {
			// 负责属性装配(包括自动注入),前面的实例只是实例化了,并没有设值
			//会回调InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation这个如果返回false,就可能导致后面的自动注入出现问题
			//然后在回调InstantiationAwareBeanPostProcessor.postProcessPropertyValues
			populateBean(beanName, mbd, instanceWrapper);
			// 完成对init-method ,还有 InitializingBean 接口,还有 BeanPostProcessor 接口的回处理
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}
		// 处理循环引用
		if (earlySingletonExposure) {
			// 检查 需要aop的类的代理类是否出现,false 不触发早期getEarlyBeanReference的执行
			// earlySingletonReference 就是早期暴露的对象
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				//earlySingletonReference 不空 getEarlyBeanReference 执行力 并 已经创建相应对象
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					//处理之前定义的<bean depends-on =""/>问题,这个不经常用到,直接跳过
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

还记得 前面AbstractBeanFactory.doGetBean 中的方法吗,这里就是放进一级缓存的地方,可以回去看看

if (mbd.isSingleton()) {
					//单例创建,getSingleton 总体逻辑就是执行createBean ,创建完之后会调用DefaultSingletonBeanRegistry.addSingleton(beanName, singletonObject);用于同步一下三级缓存的状态,主体逻辑就是放进singletonObjects (一级缓存)中,清楚其他缓存中这个beanName 的相关信息
					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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

大概的流程就这样,可能有些还讲得不是很清楚,但是已经尽力了。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值