Spring Ioc 容器Bean加载图解

接口概述
InstantiationStrategy负责实例化BeanDefinition为Bean实例的策略类,他有两个实现,分别为SimpleInstantiationStrategy和CglibSubclassingInstantiationStrategy

4.Bean加载

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
	@Override
	public Object getBean(String name) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name);
	}
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		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 + "'");
				}
			}
			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)) {
				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);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current 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()) {
					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()) {
					// 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 {
					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;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		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;
	}
}

概述:如上,是获取Bean实例的骨架代码。代码体较长,切都是高层代码,下表拆分讲解

4.1 transformedBeanName:BeanName名称转换

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
	protected String transformedBeanName(String name) {
		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
	}
	//确定原始名称,即将别名解析为规范的BeanName。
	public String canonicalName(String name) {
		String canonicalName = name;
		// 处理别名问题...
		String resolvedName;
		do {
			//从aliasMap里取出该别名所对应的beanName
			resolvedName = this.aliasMap.get(canonicalName);
			if (resolvedName != null) {
				canonicalName = resolvedName;
			}
		}
		while (resolvedName != null);
		return canonicalName;
	}
}
public abstract class BeanFactoryUtils {
	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参数,我们调用ApplicationContext的getNBean方法,传入了beanName,但是Spring支持FactoryBean,即工厂Bean,故存在获取该工厂Bean的情况(即beanName以&开头)。BeanFactoryUtils的transformedBeanName方法负责移除&符号,仅保留beanName。当然,Spring允许使用别名来检出Bean,那么canonicalName(…)就是用来解析别名,并将其规范为原始beanName的。

4.2 getSingleton

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	//存放当前处于创建中的BeanName,即当某个beanName对应的Bean实例开始创建时,会将其加入到该集合中,暗示
	//处理创建中
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));
	//用于保存BeanName和Bean实例的映射关系,是单例Bean实例的缓存
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
	//保存BeanName和创建Bean的工厂的映射关系,主要是用于循环引用
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
	//提前初始化了的单例对象
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
	//已注册了的Beans
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
	//查找单例对象,委托给getSingleton(beanName,allowEarlyReference)
	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		//首先从singletonObjects中查找是否已经实例化过beanName的实例,如果存在,直接返回,否则继续处理
		Object singletonObject = this.singletonObjects.get(beanName);
		//isSingletonCurrentlyInCreation(beanName)是判断该beanName对应的Bean是否正处于创建中
		//他的实现很简单,就是看类的singletonsCurrentlyInCreation属性(见上面,有介绍)中是否存在该beanName
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			//Bean处于创建中...
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					//
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

}

Map析意:

  • singletonObjects:其中保存的是beanName -> Bean实例
  • singletonFactories:保存的是beanName -> ObjectFactory。Spring允许循环引用,比如User类中一个House依赖,House里也有一个User的依赖,这就循环依赖了,Spring允许Setter注入循环依赖,但是不孕育构造器注入循环依赖。因此Spring会在创建Bean(即User对象)时候,优先将还未填充属性(这里House还未填充)的Bean实例,包装成一个ObjectFactory,存储进singletonFactories,这样在填充属性时,会去解析House,而House也依赖了User,因此他要通过getBean(…)方法获取Bean实例,也会进入到上面的getSingleton(…)方法中,而因为User注册了一个ObjectFactory,所以即使User还处于创建中,我们依然可以使用ObjectFactory来提取到User的实例,由此解决了循环依赖。我们看方法中在从singleFactories中取出该ObjectFactory后,调用其getObject()方法,取得一个单例对象(该单例对象就是还未填充属性House的User对象),最后,从singletonFactories中移除beanName对应的Entry,并将其加入到earlySingletonObjects中,避免不必要的对象提取。
  • earlySingletonObjects:存储的是提前创建的单例对象,这些对象并未完成全部的处理化,而是处于创建过程中,但是因为他们的内存地址,与最终的Bean实例是一致的,因此完全可以用这些提前初始化的Bean做注入(比如循环引用中)。
  • registeredSingletons:存储已注册的单例

概述:Spring会在容器启动时,将所有的单例Bean都初始化好(排除lazy-init标记的单例Bean)。因此:

  • Spring首先获取singletonObjects中是否已经有该beanName对象的单例Bean,如果存在,则直接返回;如果不存在的话,继续向下流转
  • Spring会再判断该beanName是否正在被创建,即isSingletonCurrentlyInCreation(beanName),如果确实没有处于创建中,那么中断返回null,否则继续向下流转
  • Spring继续从earlySingletonObjects中尝试提取beanName对应的Bean实例,如果提取到了,那么直接将其返回,否则继续向下流转
  • Spring会判断当前上下文是否允许循环引用,即allowEarlyReference,如果允许,则从singletonFactories中尝试提取ObjectFactory,如果不为null,则调用其getObject方法获取单例Bean对象,并将其添加到earlySingletonObjects中,并从singletonFactories移除其对应的ObjectFactory.

4.3 getObjectForBeanInstance

	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// 如果getBean(beanName)中指定的beanName以&为前缀,但是其bean实例并不是FactoryBean,那么跑出异常
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
		}
		//如果bean实例并非FactoryBean子类,那么直接返回
		//如果bean实例确实是FactoryBean,而请求的beanName亦以&开头,那么也可以直接返回
		//需要注意的是,对于工厂配置的<bean factory-method="">,Spring在singletonObjects缓存中存储的其实是工厂实例,因此我们getSingleton(beanName)得到的亦是一个工厂类实例
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}
		//如果bean实例确实是一个FactoryBean,那么我们先尝试从factoryBeanObjectCache这个缓存中提取
		//一下,这个缓存中存储的是所有FactoryBean获取的单例Bean,因此如果提取出来,那么就可以直接返回
		Object object = null;
		if (mbd == null) {
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// 判断BeanFactory是否有其对应的BeanDefinition
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//从FactoryBean中提取我们的目标对象
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}
	//提取FactoryBean中的目标对象
	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
				//额外做一次缓存查询,如果缓存中又有了目标对象,那么返回,否则执行以下逻辑
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					//核心方法!!!!直白一点将,即调用FactopryBean的getObject()方法
					object = doGetObjectFromFactoryBean(factory, beanName);
					// Only post-process and store if not put there already during getObject() call above
					// (e.g. because of circular reference processing triggered by custom getBean calls)
					//再次查询缓存,如果这时候缓存有了,那么我们可能重复getObject()了
					//代码是以已缓存中存在的目标对象为准
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						//是否对bean进行后处理,该参数是方法的入参,参数的值是依据BeanFactory中
						//是否存在其对应的BeanDefinition以及它是否是由应用程序定义的
						if (shouldPostProcess) {
							if (isSingletonCurrentlyInCreation(beanName)) {
								//临时返回未后处理的对象,尚未存储它
								return object;
							}
							//此时,将该beanName加入到singletonsCurrentlyInCreation,表示他正在处于创建中
							beforeSingletonCreation(beanName);
							try {
								//后置处理,对获得的Bean实例,应用后置处理器的postProcessAfterInitialization方法,以给他们一点机会去配置该Bean实例,比如auto-proxy它
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
								//将beanName从singletonsCurrentlyInCreation中移除,表示已经完成了创建
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {
							//将获取到的Bean实例,放到缓存中,这样以后就快了
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		else {
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}

概述:该方法是一个常用方法,当我们从缓存中获取到了单例Bean对象后,很有可能他是一个FactoryBean,对于这样类型的Bean实例,我们需要调用它的getObject()获取到目标对象。当然如果确实不是FactoryBean,则直接返回,不做处理。

4.4 getMergedLocalBeanDefinition(beanName)

根据BeanName获取merged BeanDefinition

	protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// 先从缓存中查询,减少锁的使用
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		if (mbd != null) {
			return mbd;
		}
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}
	protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
			throws BeanDefinitionStoreException {

		return getMergedBeanDefinition(beanName, bd, null);
	}
	//containingBd值得是包围内部Bean的BeanDefinition,如果是顶层BeanDefinition,那么containingBd == null
	protected RootBeanDefinition getMergedBeanDefinition(
			String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
			throws BeanDefinitionStoreException {
		//全局mergedBeanDefinitions同步互斥
		synchronized (this.mergedBeanDefinitions) {
			RootBeanDefinition mbd = null;

			// Check with full lock now in order to enforce the same merged instance.
			if (containingBd == null) {
				mbd = this.mergedBeanDefinitions.get(beanName);
			}

			if (mbd == null) {
				//如果不存在父BeanDefinition,就是没有<bean>里没有parent属性
				//到这里,我们可以确定的是此bd,必然是:
				//1.RootBeanDefinition
				//2.GenericBeanDefinition
				//且parentName都为null
				if (bd.getParentName() == null) {
					// 如果给定的BeanDefinition是RootBeanDefinition,那么直接使用给定的BeanDEfinition的拷贝,否则就创建一个RootBeanDefinition。需要提示的是,Spring有很多类型的BeanDefinition,比如ScannedGenericBeanDefinition,他是component-scan扫描得到的,
					if (bd instanceof RootBeanDefinition) {
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					}
					else {
						mbd = new RootBeanDefinition(bd);
					}
				}
				else {
					// 有父BeanDefinition,那么它必然是一个ChildBeanDefinition
					// 这中情况下,需要与其父BeanDefinition进行merge,最终获取一个merged BeanDefinition(其实Spring根本没有这个类型,而只是用了它的语义)
					BeanDefinition pbd;
					try {
						String parentBeanName = transformedBeanName(bd.getParentName());
						if (!beanName.equals(parentBeanName)) {
							//递归调用,父BeanDefinition亦可能有parentName
							pbd = getMergedBeanDefinition(parentBeanName);
						}
						else {
							BeanFactory parent = getParentBeanFactory();
							if (parent instanceof ConfigurableBeanFactory) {
								pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
							}
							else {
								throw new NoSuchBeanDefinitionException(parentBeanName,
										"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
										"': cannot be resolved without an AbstractBeanFactory parent");
							}
						}
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
								"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
					}
					// merge操作,以父BenDefinition为基础,并用子BeanDefinition覆写.
					mbd = new RootBeanDefinition(pbd);
					mbd.overrideFrom(bd);
				}

				// 如果没有设置作用于Scope,则赋值SingletonS默认值
				if (!StringUtils.hasLength(mbd.getScope())) {
					mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
				}

				// 非单例bean中包含的bean本身不能是单例bean
				// 在这里,我们将这样的merged BeanDefinition的scope设置为包围的BeanDefinition的scope
				if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
					mbd.setScope(containingBd.getScope());
				}
				// 将merged的BeanDefinition进行缓存
				if (containingBd == null && isCacheBeanMetadata()) {
					this.mergedBeanDefinitions.put(beanName, mbd);
				}
			}
			return mbd;
		}
	}

概述:创建Bean时候,Spring需要的是一个Merged BeanDefinition,即与双亲BeanDefinition合并过的BeanDefinition,最终以RootBeanDefinition的类型存在。

Spring其实并不存在MergedBeanDefinition这个类型,只是采撷了它的语义罢了。MergedBeanDefinition是基于原始BeanDefinition及其双亲BeanDefinition的信息,通过merge得到一个BeanDefinition。MergedBeanDefinition生成之后,bean属性填充之前,Spring会对该bean和该MergedBeanDefinition做一次回调,相应的回调接口是MergedBeanDefinitionPostProcessor。

4.5 getSingleton(String beanName, ObjectFactory<?> singletonFactory)

单例模式Bean的核心方法

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				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);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					singletonObject = singletonFactory.getObject();
					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 {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
}

概述:方法虽然重要,但是核心工作却并不在此,而是在由入参携带来的回调中处理的单例对象的创建工作。综合而言,合适一个模板方法:

  • beforeSingletonCreation(beanName):在单例创建之前的操作,逻辑很简单,即将beanName加入到singletonsCurrentlyInCreation这个map缓存中
  • singletonObject = singletonFactory.getObject():这里的singletonFactory就是入参传进来的ObjectFactory,我们在下面单独起一个小节来讲它。必须提醒的一点是,这个方法内除了创建Bean实例,还会自动装配,应用后置处理器
  • afterSingletonCreation(beanName):在单例创建之后的操作,逻辑也很简单,因为此时Bean已经创建完,所以就可以就从singletonsCurrentlyInCreation这个map缓存中移除掉beanName,因为已经创建完了。
  • addSingleton(beanName, singletonObject):将创建的单例对象注册,从方法中可见,它将该单例对象注册到了singletonObjects、registeredSingletons这两个缓存中,并从singletonFactories、earlySingletonObjects中移除了记录,至此完成了Bean的加载~~

4.6 createBean 核心方法

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
	/**
	* beanName:待加载的beanName
	* mbd:Merged BeanDefinition
	* args:getBean(。。。)传入的构造参数
	*/
	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;
		//确保此时bean的class已经解析出来
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 为方法覆写做准备.其实就是找出MthodOverride中的记录,并判断覆写的方法是否存在
		//他是方法注入【Method Inject】的核心!!
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 给BeanPostProcessors一个机会,让其可以返回一个代理对象,不是一个目标Bean实例
			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 {
			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);
		}
	}

概述:createBean方法为Bean加载做足了准备工作,它首先检查是否已经解析过Bean的class属性,确保构造不会有问题,然后检查该Bean中的方法注入【Methood Inject】是否有效(此时只是验证有效性,即待注入的方法是否存在)。准备工作做完,Spring给BeanPostProcessor一个机会,让其可以对Bean做代理,如果代理成功,那么直接返回代理类,不用再继续向下处理,否则就调用doCreateBean()方法,进入标准的Spring Bean创建。

下面着重讲一下resolveBeforeInstantiation(beanName,mbd)方法

	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

名词:

  • 初始化【Initialization】:此时对象已经生成
  • 实例化【Instantiation】:此时对象还没有生成

方法体的主要任务,就是应用BeanPostProcesor,我们先讲一下BeanPostProcessor,改接口只有两个API:

  1. postProcessBeforeInitialization(Object bean, String beanName) :Object ,初始化(即init-method调用)前的后置处理回调
  2. postProcessAfterInitialization(Object bean, String beanName):Object,初始化(即init-method调用)后的后置处理回调

他是一个顶级接口,子接口有:

  • InstantiationAwareBeanPostProcessor:感知实例化的BeanPostProcessor
  • DestructionAwareBeanPostProcessor:感知销毁的BeanPostProcessor
  • MergedBeanDefinitionPostProcessorLG感知BeanDefinition被Merged的BeanPostProcessor
  • SmartInstantiationAwareBeanPostProcessor:他是InstantiationAwareBeanPostProcessor的子接口
InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它在其基础上又额外提供了3个方法:

  • postProcessBeforeInstantiation(Class<?> beanClass, String beanName):Object,该方法是最先执行的方法,它在目标对象被实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替了原本该生成的目标对象,那么我们只需要为该对应应用由BeanPostProcessor声明的postProcessAfterInitialization方法即可
  • postProcessAfterInstantiation(Object bean, String beanName):Boolean,该方法用于指示是否需要对实例化后的Bean中的属性进行自动装配,如果为false,那么Spring就不会负责装配属性,否则,那就要进行自动装配了
  • postProcessProperties(PropertyValues pvs, Object bean, String beanName):PropertyValues,该方法对属性值进行修改(这个时候属性值还未被设置,不过已经通过自动装配,将待应用到属性上的值提取到了PropertyValues中,我们可以在PropertyValues之上修改它)。如果postProcessAfterInstantiation方法返回false,该方法不会被调用。我们可以在该方法内对属性值进行修改。
SmartInstantiationAwareBeanPostProcessor

它是InstantiationAwareBeanPostProcessor子类,在其基础上,又额外的声明了三个API:

  • predictBeanType(Class<?> beanClass, String beanName):Class<?>,用于预测最终由该后置处理器的 postProcessBeforeInstantiation(Class,beanName)方法返回的Bean的类型。强调一下:SmartInstantiationAwareBeanPostProcessor也是一个 InstantiationAwareBeanPostProcessor!!!
  • determineCandidateConstructors(Class<?> beanClass, String beanName):Constructor<?>[],用于选择合适的构造器,比如类有多个构造器,可以实现这个方法选择合适的构造器并用于实例化对象。该方法在postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之间调用(即实例化时调用),当然,如果postProcessBeforeInstantiation返回了代理对象,这个方法是不会执行的。
  • getEarlyBeanReference(Object bean, String beanName):Object,用于解决循环引用问题。一会会讲到,在实例化的时候,我们通过反射构造出了Bean实例,但是还没有填充属性(因为自动装配的属性可能会循环引用),会先将ObjectFactory注册到singletonFactories这个缓存变量上,这样当其他Bean循环引用它时候,即可通过该ObjectFactory.getObject()获取循环引用的属性所需装配的值(注意:其实从ObjectFactory的实现来看,他也是循环了所有的SmartInstantiationAwareBeanPostProcessor,来获取到可以提前引用的Bean)。
DestructionAwareBeanPostProcessor

它继承自BeanPostProcessor,并额外声明了一个解装操作:

  • postProcessBeforeDestruction(Object bean, String beanName):Void,在Spring销毁前,会为bean应用这个解构操作
MergedBeanDefinitionPostProcessor

它继承自BeanPostProcessor,并额外声明了一个操作:

  • postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName):Void,该方法是bean在合并BeanDefinition之后才会被调用。绝大多数的实现,是检索出本Post-Processor所感兴趣的元数据,并检查有效性,最后纳入缓存,比如AutowiredAnnotationBeanPostProcessor,它在该方法中检索出所有@Autowired、@Value、@Lookup、@Inject的注入,并件加入到元数据缓存中,在填充这些注入属性时,就可以从缓存中提取出元数据,省时。

方法体很简短,逻辑也并不复杂。首先判断当前的Merged BeanDefinition中的beforeInstantiationResolved属性是否不是FALSE,该属性用于暗示是否初始化前的后置处理器已启动,如果未启动了,那么直接返回null,否则,进入if字句。首先确保此时bean的class属性已经被解析。然后依次针对该Class类型对象,应用postProcessBeforeInstantiation(beanClass,beanName)方法,然后如果确实有被代理,在依次对该代理对象应用postProcessAfterInitialization()方法。

回到主题

细心的读者应该看到,在applyBeanPostProcessorsBeforeInstantiation(…)方法中,我们其实只应用InstantiationAwareBeanPostProcessorr的特殊方法:postProcessBeforeInstantiation,如果被代理,那么BeanFactory.getBean(…)就可以提前结束了,而如果没有被代理,那么就按照常规的方式,创建Bean

InstantiationAwareBeanPostProcessor接口是BeanPostProcessor接口的子接口,它的作用通常是用于抑制特定目标bean的默认实例化,比如创建具有特殊TargetSources的代理,或者为了实现额外的注入策略,比如属性注入
PS:后面会讲

4.7 doCreateBean

Spring中do开头的方法,都属于核心方法

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

		// 声明一个BeanWrapper,用于作为Bean实例的容器.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//创建Bean实例(即反射创建),见4.7.1
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//获取BeanWrapper这个容器中盛的Bean实例以及其Class对象
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
		// 见4.7.2
		// 允许后置处理器修改merged BeanDefinition,此时Bean实例岗创建,属性还未填充,因此要赶在之前,对BeanDefinition做修改
		// MergedBeanDefinitionPostProcessor中声明了postProcessMergedBeanDefinition方法,
		// Spring允许该接口的实现,通过实现该方法,获得修改BeanDefinition的能力,当然并不一定真的强制要修改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;
			}
		}
		// 见4.7.3
		// 如果允许循环引用,那么我们将在此刻,向singletonFactories这个缓存对象中
		// 添加一个beanName -> ObjectFactory的Entry,用于解决循环引用
		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");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 初始化Bean实例
		Object exposedObject = bean;
		try {
			//见4.7.4 填充属性
			populateBean(beanName, mbd, instanceWrapper);
			//见4.7.5 初始化
			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) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					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 " +
								"'getBeanNamesOfType' 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;
	}
}

概述:我挑选比较重要的流程,做一个精简:

  1. 根据目标对象Class,反射构造器获取Bean实例
  2. 为该Bean应用postProcessMergedBeanDefinition,以在装配属性前,修改Merged BeanDefinition
  3. 为解决循环引用,向singleFactories缓存中加入beanName -> ObjectFactory这个Entry
  4. 填充属性
  5. 调用init-method(注意:在调用前后会执行BeanPostProcessor的postProcessBeforeInitialization方法和postProcessAfterInitialization方法)
  6. 提前曝光
  7. 注册解构该Bean的后置处理器

4.7.1 createBeanInstance

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 确保此时待创建的Bean的Class已经解析完成
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		//如果有factory-method,即这是一个FactoryBean
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 判断是否已经对该Merged BeanDefinition做过解析
		// 需要提的一点是,merged BeanDefinition也会被缓存,与BeanDefinition缓存的地方不一样
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					//是否解析过
					resolved = true;
					//预示已经解析成出的可用的构造器的参数是否已解析过(因为重载,一个类可以有多个构造器)
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		//如果解析过,就判断是否构造器参数是否已解析,如果true,那么直接构造器注入
		//如果否,那么反射无参构造器进行实例化
		//其实resolved = true,就已经表示解析出可用的构造器了
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}
		// 到这里,已经确定没有被解析过 
		// 下面我们先决定使用哪个构造器,并判断该构造器的参数是否有自动装配的
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// 普通Bean实例化,直接使用无参构造器,反射
		return instantiateBean(beanName, mbd);
	}
	protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
			throws BeansException {

		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					if (ctors != null) {
						return ctors;
					}
				}
			}
		}
		return null;
	}

概述:该方法逻辑其实很复杂,尤其是决定使用哪个构造器。在前面讲BeanPostProcessor时候,我们提到过SmartInstantiationAwareBeanPostProcessor,它声明的determineCandidateConstructors(…)方法就是用来决断使用哪个构造器的。当决断的结果不为NULL,我们可以使用构造器自动装配,即autowireConstructor(…)来构建Bean的实例,逻辑很复杂。而如果决断的结果为NULL,说明只能用默认的无参构造器反射构建Bean实例,即instantiateBean(…)方法

instantiateBean,使用发射构建Bean实例,它涉及Spring的一个策略模式。Spring会在反射之前,先获取实例化策略,默认的InstantiationStrategy是CglibSubclassingInstantiationStrategy,它是SimpleInstantiationStrategy的子类,然后选择该策略对象,进行Bean的创建。

CglibSubclassingInstantiationStrategy是一个默认的策略对象,不要认为用它构建的对象都是代理,只有调用instantiateWithMethodInjection(…)方法构建的对象才是又CGLib代理的对象(只有待构建的Bean的BeanDefinition中的methodOverrides属性中有值时候,才会被调用),而调用instantiate(…)方法构建的,是反射无参构造器创建的原生对象。

4.7.2 applyMergedBeanDefinitionPostProcessors

	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

概述:在讲BeanPostProcessor时,我们提到过MergedBeanDefinitionPostProcessor,它在BeanPostPorocessor的基础上,额外声明了一个postProcessMergedBeanDefinition(…)方法,用于作为BeanDefinition被Merged后的回调。

上述方法的体量很小,循环所有注册的BeanPostProcessor,并筛选出MergedBeanDefinitionPostProcessor类型的,调用其postProcessMergedBeanDefinition(…)方法。那么这个方法到底做了什么?我们以看下面这个具体的实现:

class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
	private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		//注册了beanName与其是否单例的映射关系
		this.singletonNames.put(beanName, beanDefinition.isSingleton());
	}
}

再看另一个例子:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		//找出所有@Autowired/@Value/@Lookup/@Inject的需要自动装配的元数据,将将其纳入到AutowiredAnnotationBeanPostProcessor
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		//对元数据做校验
		metadata.checkConfigMembers(beanDefinition);
	}
	private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
		// Fall back to class name as cache key, for backwards compatibility with custom callers.
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		// Quick check on the concurrent map first, with minimal locking.
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		if (InjectionMetadata.needsRefresh(metadata, clazz)) {
			synchronized (this.injectionMetadataCache) {
				metadata = this.injectionMetadataCache.get(cacheKey);
				if (InjectionMetadata.needsRefresh(metadata, clazz)) {
					if (metadata != null) {
						metadata.clear(pvs);
					}
					metadata = buildAutowiringMetadata(clazz);
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}
}

Spring允许我们实现MergedBeanDefinitionPostProcessor,在其postProcessMergedBeanDefinition方法中修改MergedBeanDefinition.

4.7.3 addSingletonFactory

为了解决循环引用,Spring使用ObjectFactory提前暴露还未初始化结束的Bean.

	//首先判断是否需要代理提前曝光,即①是否单例②是否允许循环引用③当前BeanName是否处于构建中,全部满足,则提前曝光
	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");
		}
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}
	//将beanName和ObjectFactory添加到单例工厂中
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			//如果singletonObjects存在beanName,那么说明它已经创建结束了
			if (!this.singletonObjects.containsKey(beanName)) {
				//向singletonFactories添加一个beanName-> ObjectFactory
				this.singletonFactories.put(beanName, singletonFactory);
				//移除提前单例对象中的缓存
				this.earlySingletonObjects.remove(beanName);
				//并将beanName加入到registeredSingletons缓存中
				this.registeredSingletons.add(beanName);
			}
		}
	}
	//获取提前Bean引用,循环引用导致循环中所有Bean都没有创建结束,但是如果都不提供一个引用句柄,那么循环就死锁了
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		//首先判断是否存在SmartInstantiationAwareBeanPostProcessor类型的BeanPostProcessor
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					//由SmartInstantiationAwareBeanPostProcessor决定如何暴露这个提前Bean引用
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		//返回
		return exposedObject;
	}

概述:我们假设不存在任何SmartInstantiationAwareBeanPostProcessor,那么循环引用时,其实就是将我们传入getEarlyBeanReference方法中bean入参(即刚实例化,还未填充属性的Bean),作为返回值返回了。而如果存在SmartInstantiationAwareBeanPostProcessor,那么循环并分别应用其getEarlyBeanReference(…)方法,以得到一个处理过的Bean对象,多见于自动代理情况下。

然后我们梳理一下这几个缓存的使用:(场景,A 引用 B ,B 又引用 A)

  1. 当A实例化完成,我们首先将A的ObjectFactory加入到singletonFactories中
  2. 移除earlySingletonObjects中关于A的记录
  3. 当populateBean(A)时候,我们需要为其填充B,getBean(B)
  4. B实例化完成,然后我们也将B的ObjectFactory加入到singletonFactories中
  5. 移除earlySingletonObjects中关于B的记录
  6. 当populateBean(B)时,我们又getBean(A)
  7. getBean会调用getSingleon(A),从缓存取一下试试,方法前面有讲,先看singletonObjects是否有A,肯定没有,然后又看isSingletonCurrentlyInCreation(A),这个有,确实在创建中,然后earlySingletonObjects中取,发现没有,因为我们清空过了,那么这就会再去singletonFactories中查找其对应的ObjectFactories,找到了,然后调用ObjectFactory.getObject() ,其实背地里,他就是来调用getEarlyBeanReference(…),拿到了A引用,然后填充完属性,初始化完,最后将其加入到singletonObjects中
  8. 这时候B已经可用了,然后将B的引用交给A,A也完成了属性的填充
  9. A开始处理华,即init-method
  10. 10.A将自己注册到singletonObjects中
  11. OK

4.7.4 populateBean

属性的自动装配!!1很重要的一点

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				return;
			}
		}


		// 给InstantiationAwareBeanPostProcessors一个机会,让其可以在Properties set之前修改bean的状态
		// 而且,postProcessAfterInstantiation()方法的返回值,预示着是否需要继续下面的自动装配代码
		// 如果返回false,俺么就下面的自动装配就不会再走了,populateBean到此也就为止了!!
		boolean continueWithPropertyPopulation = true;

		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}
		//如果不需要继续属性装配,那么return中断
		if (!continueWithPropertyPopulation) {
			return;
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		//查看Merged BeanDefinition是否有指示是by-name还是by-type进行自动装配
		if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// By-Name.最简单,直接BeanFactory.getBean(name)
			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// By-Type.较为复杂,需要适配List/Map等类型
			if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}
		//判断是否存在InstantiationAwareBeanPostProcessor
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//是否需要深度检查
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
		//如果存在InstantiationAwareBeanPostProcessor,那么可能需要其做自动装配
		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			//如果存在InstantiationAwareBeanPostProcessor,循环,并分别应用
			//其postProcessProperties(...)方法,这个方法的作用很重,就是为bean填充上属性
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
		//如果还有其他可以为Bean装填的属性键值对,那么为其应用,比如我们配置<bean>时候的<property>
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

概述:

  1. 给InstantiationAwareBeanPostProcessors一个机会,调用其postProcessAfterInstantiation(…)方法,该方法可以修改Bean的状态(即可以随意修改它),如果返回值false,暗示不需要继续自动转给了,方法结束
  2. 检查Merged BeanDefinition中书否有标志By-Name Or By-Type的自动装配,如果有,则分别应用对应的方法进行装配
  3. 再次判断InstantiationAwareBeanPostProcessor是否存在,如果存在,在将bean交给它们的postProcessProperties(…)方法,进行自动装配,注意,postProcessPropertyValues()这个方法已经废弃了。
  4. 最后检查pvs:PropertyValues中是否还有没有东西待装配,如果有,那么applyPropertyValues()以对这些属性装配,通常都是< property name="" value="">
  5. OK

需要提示一点,在装配过程中必然存在还没有实例化的Bean,这种情况下就会根据情况,对这些Bean进行实例化~~比如By-Name中,就是直接调用beanFactory.getBean(),InstantiationAwareBeanPostProcessor在自动装配时,比较依赖于实现,如CommonAnnotationBeanPostProcessor只会装配@Resource的属性,而AutowiredAnnotationBeanPostProcessor则会装配@Autowired/@Value/@Inject/@Lookup的属性。

4.7.5 initializeBean

	private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		//假设该Bean实现了一些Aware接口,那么此时就是将其需要感知的东西赋值进去
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//Init之前的BeanPostProcessor
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//Init调用
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			//Init之后的BeanPostProcessor
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

概述:属性装填后,就是要运行Bean的init-method了,我们知道BeanPostProcessor中声明了两个方法,分别在init前后调用,那么执行点就在这个方法里。

至此,Bean的加载基本结束

4.7.5 关于提前曝光

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					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已经基本结束,我们前面向singletonFactories中添加了一个beanName -> ObjectFactory,用于解决循环引用,此时getSingleton(beanName,false)再次去缓存看一下self的当前状况,注意参数里的false,结合源码就能看懂。如果返回的earlySingletonReference != NULL,那么确实发生循环引用了。

SSO

4.7.6 registerDisposableBeanIfNecessary

	protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);	
		//如果BeanDefinition表示它并不是prototype,而且需要解构
		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
			//单例
			if (mbd.isSingleton()) {
				// 为该给定的Bean注册一个DisposableBean的实现,用于解构
				registerDisposableBean(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
			else {
				// 自定义作用域中的Bean
				Scope scope = this.scopes.get(mbd.getScope());
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
				}
				scope.registerDestructionCallback(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
		}
	}

概述:为需要解构的Bean,注册一个DisposableBean的实现,用于解构,直白一点,就是会在Bean被破坏时调用其Destroy方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值