深入理解Spring IOC(四)、 实例化开启

654 阅读21分钟

之前的文章:

1、深入理解Spring IOC(一) 、统一资源的加载

2、深入理解Spring IOC(二) 、从xml到BeanDefinition

3、深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作

接下来我们进入AbstractApplicationContext中的finishBeanFactoryInitialization这个方法,我们先一起看看它的代码:

                                                                代码块1
        protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 先实例化ConversionService(如果有)
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// 实例化LoadTimeWeaverAware的实现类
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// 在这里要将beanDefiniton冻结住,因为要进行实例化了,不希望beanDefiniton有任何的变化
		beanFactory.freezeConfiguration();

		// 要实例化几乎除过实现了BeanFactoryPostProcessor、BeanPostProcessor的类之外的所有类
		// 因为这两个的实现类之前已经实例化过了
		beanFactory.preInstantiateSingletons();
	}

前面的代码不属于重要的部分,我们直接看最后一处的方法preInstantiateSingletons,该方法的实现位于DefaultListableBeanFactory中:

                                                                代码块2
        @Override
	public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Pre-instantiating singletons in " + this);
		}

		List<String> beanNames;
		synchronized (this.beanDefinitionMap) {
			// this.beanDefinitionNames,创建beanDefinitionNames的副本beanNames
			// 用于后续的遍历,以允许init等方法注册新的bean定义
			// this.beanDefinitionNames 中存储的是在注册BeanDefinition的时候存进来的bean名称
			beanNames = new ArrayList<String>(this.beanDefinitionNames);
		}
		// 遍历,用bean名称初始化
		for (String beanName : beanNames) {
			// 获取beanName对应的RootBeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			
			// 如果不是抽象并且是单例,并且不是懒加载,才会去进行初始化
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 1. 如果不是FactoryBean就直接初始化,是的话先拿到FactoryBean本身,再根据isEagerInit决定
				// 是否调用getObject进行初始化
				if (isFactoryBean(beanName)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					// 2.这个if else主要是用于判断是否需要先加载(饥饿加载)
					// isEagerInit这个变量值其实就是SmartFactoryBean中isEagerInit()方法,只不过一个是直接获取,
					// 另外一个是通过“特权”去执行
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					} else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					
					// 如果isEagerInit则实例化bean
					if (isEagerInit) {
						getBean(beanName);
					}
				} else {
					getBean(beanName);
				}
			}
		}
	}

我们来看代码块2的1处调用的isFactoryBean方法

代码块2.1

                                                                代码块3
        @Override
	public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
		// 1. 处理名称
		String beanName = transformedBeanName(name);
		
		// 2. 从缓存中拿实例并判断
		Object beanInstance = getSingleton(beanName, false);
		if (beanInstance != null) {
			return (beanInstance instanceof FactoryBean);
		// 如果this.singletonObjects包含这个beanName的key,则直接返回false
		}else if (containsSingleton(beanName)) {
			return false;
		}

		// 从beanDefinition中做检查
		// 本BeanFactory对象中没有这个beanName的BeanDefinition && 父BeanFactory是个ConfigurableBeanFactory
		if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
			return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
		}

		// 根据class判断是不是个FactoryBean
		return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
	}

首先看看代码块3中1处处理名称的逻辑:

代码块3.1

                                                                代码块4
    protected String transformedBeanName(String name) {
		// 调用canonicalName方法去处理BeanFactoryUtils.transformedBeanName的结果
		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
	}

上面代码块调用的方法参数是BeanFactoryUtils中的transformedBeanName返回的,我们先来看这个方法:

                                                                代码块5
    public static String transformedBeanName(String name) {
		Assert.notNull(name, "'name' must not be null");
		String beanName = name;
		// beanName 是否以 “&” 开头,如果以它开头,将这个用String中的substring方法截掉
		while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
			beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
		}
		return beanName;
	}

很多人会疑惑,为什么以“&”开头,就截取掉呢?我们来看看BeanFactory中定义的“&”的地方:

                                                                代码块6
public interface BeanFactory {

	/**
	 * Used to dereference a {@link FactoryBean} instance and distinguish it from
	 * beans <i>created</i> by the FactoryBean. For example, if the bean named
	 * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
	 * will return the factory, not the instance returned by the factory.
	 */
	String FACTORY_BEAN_PREFIX = "&";
.....

我们可以清楚的从这个变量的注释上面看到:如果某个bean是个FactoryBean类型的东西,但是它注册进IOC容器的名称是用“&”开头,那么代表它想获取的是FactoryBean本身,而不是它的getObject所返回的对象。因此,去拿真正的bean的名称的时候是需要去掉这个前缀的。然后我们继续看代码块4调用的这个canonicalName方法

代码块4.1

                                                                代码块7
        public String canonicalName(String name) {
		String canonicalName = name;
		// Handle aliasing...
		String resolvedName;
		do {
			// 去根据别名拿真正的名称
			// aliasMap的key是别名,value是名称
			resolvedName = this.aliasMap.get(canonicalName);
			if (resolvedName != null) {
				canonicalName = resolvedName;
			}
		}
		while (resolvedName != null);
		return canonicalName;
	}

我们再回到代码块3,来看里面2处的方法,注意此时第二个参数是false:

代码块3.2

                                                                代码块8
        protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// 先尝试从成品的缓存中拿成品
		Object singletonObject = this.singletonObjects.get(beanName);
		// 如果没成品并且正在创建中
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				// 从提前曝光的对象中尝试获取
				singletonObject = this.earlySingletonObjects.get(beanName);
				// ***** 如果半成品也是null并且允许创建早期的单例引用,
				if (singletonObject == null && allowEarlyReference) {
					// 去拿对象的ObjectFactory
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						// 通过ObjectFactory创建半成品,然后放到半成品对象的缓存中
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}

注意注释中*****开头的,因为此时传过来的参数是false,所以在这之后的代码此时都是没有被执行的。这段代码涉及到三层缓存的概念,所谓的三层缓存,其实就是singletonObjects,earlySingletonObjects,singletonFactories这三个Map,这三层缓存对解决循环依赖有着重要的意义,如果你现在不明白,就当混个脸熟,完了回过头来看,相信会容易理解很多,现在可以理解为这个方法就是从缓存里取已经创建的bean实例的。

代码块2.2

我们继续看代码块2的第2处isEagerInit属性的获取这里,因为对于spring来说,它去拿这个isEagerInit属性,很可能是去调用第三方jar包的东西,而这个第三方jar包却需要操作一些需要权限才可以操作的东西,因此这里如果检测到SecurityManager,说明程序是有权限校验的,这时候就需要通过AccessController.doPrivileged来执行。我们接下来看这里调用的getBean方法:

                                                                代码块9
        @Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

可以看到这个方法是直接调用的doGetBean,我们来看看这个方法:

                                                                代码块10
        @SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		// 1. 解析bean的名称
		final String beanName = transformedBeanName(name);
		Object bean;

		// 2.先尝试从缓存中取一波
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			// 3. 这块这个主要是针对FactoryBean的处理,如果只是个普通bean,则直接返回其本身
			// 如果是个FactoryBean,则要根据name判断
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		} else {
			// 4. 这个主要针对的是prototype(多例)的bean的循环依赖的检查(spring解决不了多例的循环依赖)
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			BeanFactory parentBeanFactory = getParentBeanFactory();
			// 如果父BeanFactory存在,并且本BeanFactory中不存在这个beanName的BeanDefinition
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// 5. 将别名解析成真正的bean的名字
				String nameToLookup = originalBeanName(name);
				// 使用父BeanFactory创建实例
				if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}else {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
			
			// 6. 如果不是仅仅检查类型,则把beanName放到alreadyCreated缓存中
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}
			
			// 注意哈:其实到这里,真正创建bean的流程才开始
			try {
				// 7. 拿到这个beanName对应的BeanDefinition对应的RootBeanDefinition
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				
				// 将mbd打印成json (这是作者自己增加的代码)
				System.out.println(JSON.toJSON(mbd).toString());
				
				// 8. 检查这个mbd是否合法
				checkMergedBeanDefinition(mbd, beanName, args);

				// 先实例化这个bean所依赖的bean,mbd.getDependsOn()是获取mbd所
				// 依赖的bean实例的名称(xml中对应bean标签depend-on属性)
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dependsOnBean : dependsOn) {
						// 这块这个是检查循环依赖的
						// 例:如果有这么两个类A和B,A中有个成员属性B,B中有个成员属性A,当先实例化A的时候,发现B还没有实例化
						// 然后去调用上面的getBean方法(相当于递归),然后走到这里发现B又依赖A,然后就报异常了
						// 这个会在两个bean标签的depend-on属性相互指向对方时发生
						if (isDependent(beanName, dependsOnBean)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
						}
						// 9. 将依赖关系注册
						registerDependentBean(dependsOnBean, beanName);
						// 然后实例化依赖的那个bean
						getBean(dependsOnBean);
					}
				}

				// 这里开始创建mbd对应的bean
				
				// 创建单例
				if (mbd.isSingleton()) {
					// 10. 获取bean实例
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								//  调用创建bean的方法
								return createBean(beanName, mbd, args);
							}catch (BeansException ex) {
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					// 返回bean本身,(这个方法我们之前讲过,是针对FactoryBean处理的那个方法)
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				// 创建prototype的bean
				}else if (mbd.isPrototype()) {
					// 如果是个prototype的实例,那就创建个新的
					Object prototypeInstance = null;
					try {
						// 11. 创建prototype前的检查
						beforePrototypeCreation(beanName);
						// 调用创建bean的方法
						prototypeInstance = createBean(beanName, mbd, args);
					}finally {
						// 12.创建prototype后的检查
						afterPrototypeCreation(beanName);
					}
					// 返回bean本身,(和上面if一个方法)
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				// 创建其他scope的bean
				}else {
					String scopeName = mbd.getScope();
					// 拿到对应scope的缓存
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
					}
					try {
						// 创建bean实例,注意这里重写了ObjectFactory的getObject方法
						Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
							@Override
							public Object getObject() throws BeansException {
								// 创建prototype前的检查
								beforePrototypeCreation(beanName);
								try {
									// 调用创建bean的方法
									return createBean(beanName, mbd, args);
								}finally {
									// 创建prototype后的检查
									afterPrototypeCreation(beanName);
								}
							}
						});
						// 返回bean本身,(和上面if一个方法)
						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;
			}
		}

		// 检查类型,如果不是结果所需要的类型,则尝试类型转换
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			try {
				return getTypeConverter().convertIfNecessary(bean, requiredType);
			}catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type [" +
							ClassUtils.getQualifiedName(requiredType) + "]", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

这个方法代码比较长,我们对着我的注释,一个一个来看,1处在上面已经讲过,这里和上面的逻辑是完全一样的,我们来看代码块10中2处的代码所调用的方法:

代码块10.2

                                                            代码块11
        @Override
	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}

这里调用的方法还是代码块8的那个方法,只不过注意此时参数为true了,true和上面的false有什么区别呢?我们可以翻到代码块8看看,当这个参数为true的时候,是允许使用ObjectFactory来创建早期的引用的,不过你可能还不明白什么是早期引用,没关系,先记住这个问题,继续往下看,自然会明白。

我们继续回到代码块10中,去看第3处代码,你应该注意到,能走到这处,说明上面从缓存中取出来的sharedInstance应该不是null,并且本方法参数中args要为null,我们在代码块9中可以看到args确实是null,所以可以肯定,如果sharedInstance不是null,那的确是可以进到3这里来的:我们来看看3处调用的方法。

代码块10.3

                                                            代码块12
        protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

		// 1.如果名称是个factorybean前缀(&)开头的但是却不是FactoryBean,则抛出异常
		//  (当bean名称前缀是“&”的时候,代表这玩意是个FactoryBean的实例)
		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}

		// 2.if的前半个条件意思是如果不是FactoryBean,则直接返回beanInstance
		// 	 后半个条件是当是个FactoryBean的时候,并且用&开头,则返回beanInstance
		// (以“&”为前缀代表想获取的是FactoryBean本身,而不是它getObject返回的)
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

		// 3.当代码走到这里的时候,beanInstance一定是一个FactoryBean
		// 	并且想要返回的是FactoryBean中getObject所返回的,object即为返回的结果
		Object object = null;
		if (mbd == null) {
			//4. 尝试从factoryBeanObjectCache(factoryBean创建的对象的缓存)里拿
			object = getCachedObjectForFactoryBean(beanName);
		}
		// 如果从factoryBean创建的对象的缓存没拿到,就走这个if
		if (object == null) {
			//5. 因为一定是FactoryBean,所以可以直接强转
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			//6. 如果mbd为空,并且beanDefinitionMap中包含着这个bean,则去根据这个获取RootBeanDefinition
			if (mbd == null && containsBeanDefinition(beanName)) {
				// 7. 获取beanName对应的RootBeanDefinition
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			//8. 判断Beaneifinition是不是合成的(多次debug这里都是false)
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

第1处的注释写的很清楚,我们来看看它调用的方法:

                                                            代码块13
        public static boolean isFactoryDereference(String name) {
		// BeanFactory.FACTORY_BEAN_PREFIX 值是“&”
		return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
	}

是不是很简单?其实源码中很多地方也没那么难的😊,第2处也很简单了,我们来看看第4处调用的方法的代码:

                                                            代码块14
        // 下面方法调用的cache
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);
	
	protected Object getCachedObjectForFactoryBean(String beanName) {
		// factoryBeanObjectCache就是factoryBean创建的对象的缓存
		Object object = this.factoryBeanObjectCache.get(beanName);
		return (object != NULL_OBJECT ? object : null);
	}

这个也是个很简单的方法,我们继续看代码块12中的第6处的这个if条件里调用的方法:

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

这个beanDefinitionMap就是我们之前讲注册beanDefinition时候的那个map,我们再继续看代码块12中的第8处代码,注意我把第7处的跳过了哈,因为现在不是讲这个第7处方法调用的代码的最好时候,你现在先去根据注释理解,等该讲的时候,我会让你一下子明白的。

                                                            代码块16
        protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		//  FactoryBean实例是单例 && FactoryBean实例已经存在单例缓存this.singletonObjects中
		if (factory.isSingleton() && containsSingleton(beanName)) {
			// getSingletonMutex()返回的是单例缓存this.singletonObjects
			synchronized (getSingletonMutex()) {
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
					// 1. 使用factoryBean创建bean
					object = doGetObjectFromFactoryBean(factory, beanName);
					// 如果缓存中已经存在,则用缓存中的替换上面生成的
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}else {
						// 2. 既然object已经生成了,则执行所有BeanPostProcessor的
						// 	postProcessAfterInitialization方法
						if (object != null && shouldPostProcess) {
							try {
								object = postProcessObjectFromFactoryBean(object, beanName);
							}catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
						}
						// 放入factoryBeanObjectCache缓存
						this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
					}
				}
				return (object != NULL_OBJECT ? object : null);
			}
		}else {
			// 使用factoryBean创建bean,然后再执行所有的BeanPostProcessor(和上面一样)
			// 不同点是prototype这种情况的话,不会放到缓存中
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (object != null && shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}

直接来看代码块16里第1处调用的方法:

                                                            代码块17
        private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {

		Object object;
		try {
			// 就是简单调用了FactoryBean的getObject而已,只不过if
			// 代码块的是特权调用,else里是直接调用
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
								return factory.getObject();
							}
						}, acc);
				}catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}else {
				object = factory.getObject();
			}
		}catch (FactoryBeanNotInitializedException ex) {
			throw new BeanCurrentlyInCreationException(beanName, ex.toString());
		}catch (Throwable ex) {
			throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
		}

		// 如果结果object此时还是null,并且这个FactoryBean还是在创建的这个过程中,则
		// 抛出异常,此时说明初始化流程是存在问题的
		if (object == null && isSingletonCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(
					beanName, "FactoryBean which is currently in creation returned null from getObject");
		}
		return object;
	}

这段代码是也是段纸老虎代码,看着很长,其实很简单,就是调用了FactoryBean的getObject方法而已,我们再来看代码块16的if中调用的代码,注意真正被调用的方法在AbstractAutowireCapableBeanFactory中:

                                                            代码块18
        @Override
	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
		return applyBeanPostProcessorsAfterInitialization(object, beanName);
	}

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
		// 执行所有BeanPostProcessor的postProcessAfterInitialization方法
		Object result = existingBean;
		// 遍历执行
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			result = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (result == null) {
				return result;
			}
		}
		return result;
	}

至此,代码块10中的3处就完了,是不是感觉费了很久功夫呢?其实阅读源码就是这样,方法中套方法,经常都是你看完了一个很长的方法,再回到原来的方法,发现其实只是这个方法中的一行代码,我早些时候经常都是边看边吐血,因为真的太难了,不过好在一遍又一遍的坚持了下来,完了还是很开心的。

代码块10.4

小小的吐槽完了,继续看代码块10中的第4处,这里主要是针对prototype的循环依赖检查,这个是当A中有B,B中有A并且A和B的scope都是prototype的时候会在这里抛异常,spring解决不了prototype的循环依赖,原因也简单,你想嘛,你想要一个新的A,创建A的时候发现A需要一个新的B,所以要去创建B,但是创建B的时候,又要一个新的A,然后就陷入无限循环,最后要么StackOverFlowException,要么OutOfMemoryError,所以spring就在这里直接抛异常了。

代码块10.5

接下来是代码块10的第5处调用的方法,这个方法是用来获取bean的原始名称的:

                                                            代码块19
        protected String originalBeanName(String name) {
		String beanName = transformedBeanName(name);
		// 如果name中有"&",那就给beanName也加上“&”
		// 因为transformedBeanName中去掉了“&”
		if (name.startsWith(FACTORY_BEAN_PREFIX)) {
			beanName = FACTORY_BEAN_PREFIX + beanName;
		}
		return beanName;
	}

第一行的代码解释见代码块5,剩下的很简单了,我们继续代码块10中的第6处调用的方法:

代码块10.6

                                                            代码块20
        protected void markBeanAsCreated(String beanName) {
		// alreadyCreated 是已经创建的和正准备去创建的集合
		if (!this.alreadyCreated.contains(beanName)) {
			this.alreadyCreated.add(beanName);
		}
	}

依然是个很简单的方法,代码块10中第6处调用这个方法,是因为准备去创建这个bean了。我们继续代码块10中第7处,这下要讲这个之前代码块12和代码块2中跳过的getMergedLocalBeanDefinition(String name)方法了,我们先贴出来这个方法的代码哈:

代码块10.7

                                                            代码块21
    // 首先调用的方法
    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);
	}

	protected RootBeanDefinition getMergedBeanDefinition(
			String beanName, BeanDefinition bd, BeanDefinition containingBd) throws BeanDefinitionStoreException {
		// 加锁防止并发
		synchronized (this.mergedBeanDefinitions) {
			// 这个是返回结果
			RootBeanDefinition mbd = null;

			// Check with full lock now in order to enforce the same merged instance.
			// 之所以还在这里get一下,是因为防止从上面的方法到这里的时候已经有别的线程把这个RootBeanDefinition创建好了
			// 现在在这个串行的操作中,如果没有get到,说明就是确实还没有
			if (containingBd == null) {
				mbd = this.mergedBeanDefinitions.get(beanName);
			}
			// 若不存在于缓存中,则进行下一步操作
			if (mbd == null) {
				if (bd.getParentName() == null) {
					// 如果没有父定义的BeanDefinition,则不需要合并,直接通过深克隆的方式
					// 创建RootBeanDefinition
					if (bd instanceof RootBeanDefinition) {
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					} else {
						mbd = new RootBeanDefinition(bd);
					}
				} else {
					// 存在父定义BeanDefinition,递归着去和父定义的合并
					BeanDefinition pbd;
					try {
						// 获取父BeanDefinition真正的名称
						String parentBeanName = transformedBeanName(bd.getParentName());
						if (!beanName.equals(parentBeanName)) {
							// 递归调用
							pbd = getMergedBeanDefinition(parentBeanName);
						} else {
							if (getParentBeanFactory() instanceof ConfigurableBeanFactory) {
								// 强转再递归调用
								pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName);
							} else {
								throw new NoSuchBeanDefinitionException(bd.getParentName(),
										"Parent name '" + bd.getParentName() + "' 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);
					}
					// 根据父定义深度拷贝一个新的
					mbd = new RootBeanDefinition(pbd);
					// 用子覆盖父
					mbd.overrideFrom(bd);
				}

				// 默认单例
				if (!StringUtils.hasLength(mbd.getScope())) {
					mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
				}
				// 设置scope,此时containingBd还是null
				if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
					mbd.setScope(containingBd.getScope());
				}
				// containingBd是null && this.cacheBeanMetadata && 该bean是否可以被缓存
				// 这里这三个条件走到这块一般都成立了
				if (containingBd == null && isCacheBeanMetadata() && isBeanEligibleForMetadataCaching(beanName)) {
					this.mergedBeanDefinitions.put(beanName, mbd);
				}
			}

			return mbd;
		}
	}

这个方法的代码不算难,但是为什么要把其他类型的BeanDefinition都转成RootBeanDefinition呢?因为RootBeanDefinition是被spring作为在运行时候的统一使用的BeanDefnition(即在创建bean实例时候使用的统一的BeanDefnition),里面还包含了解析过的构造方法缓存,方法参数缓存其他缓存信息,如果说其他类型的BeanDefnition都是用于把元数据(就是如xml或者注解)表达为spring可以认识的信息的话,那么RootBeanDefinition就是把spring已经认识出来的信息表达为了可以实际去使用的信息。

我们继续看代码块10中第8处方法调用的方法:

代码块10.8

                                                                代码块22
        protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)
			throws BeanDefinitionStoreException {

		// 如果是抽象则抛出异常
		if (mbd.isAbstract()) {
			throw new BeanIsAbstractException(beanName);
		}

		// 如果args不是null但是beanDefinition对应的类型却不是prototype,则抛出异常
		// 这个是因为当args不是null的时候,代表需要动态参数实例化bean,而此时该bean的作用域只能是prototype
		if (args != null && !mbd.isPrototype()) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
					"Can only specify arguments for the getBean method when referring to a prototype bean definition");
		}
	}

代码块22我没有标数字,我稍微解释一下这里面的第二处注释,方法参数args不为null的情况是当你调用了applicationContext中带参数的getbean方法或者是beanFactory中带参数的getbean方法时候,这里才不是null,但是高版本的spring已经把这个对参数检查去掉了。

代码块10.9

继续看代码块10中第9处,此时已经找到我们这个beanName对应的bean需要依赖的bean是哪些bean了,因此将依赖关系注册进去:

                                                                代码块23
    public void registerDependentBean(String beanName, String dependentBeanName) {
		// 获取真正的bean名称
		String canonicalName = canonicalName(beanName);
		// 这段代码是将beanName和dependentBeanName的依赖关系注册到dependentBeanMap中
		// 注意这个是beanName依赖dependentBeanName
		synchronized (this.dependentBeanMap) {
			Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
			if (dependentBeans == null) {
				dependentBeans = new LinkedHashSet<String>(8);
				this.dependentBeanMap.put(canonicalName, dependentBeans);
			}
			dependentBeans.add(dependentBeanName);
		}
		
		// 这段代码是将beanName和dependentBeanName的依赖关系注册到dependentBeanMap中
		// 注意这个是dependentBeanName依赖beanName,关系是反着的
		// 就是说当A中有B,B中有A和C的时候,C中又有A,spring通过这两个map就能知道
		// A依赖了B,而依赖A的有A和C
		synchronized (this.dependenciesForBeanMap) {
			Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
			if (dependenciesForBean == null) {
				dependenciesForBean = new LinkedHashSet<String>(8);
				this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
			}
			dependenciesForBean.add(canonicalName);
		}
	}

里面第一行注释调用的方法在本篇的代码块7已经讲过,其他的都很容易理解了,我们继续回过头来看代码块10中的第10处,在看这里调用的getSingleton方法之前,你需要注意到这个getSingleton方法和之前的不一样,此外,这个方法调用的时候所传的第二参数是个实现了ObjectFactory的匿名内部类,并且在它的实现里面调用了createBean方法,限于篇幅,createBean方法会在下一篇讲,不然估计你可能会晕的更厉害。我们来看这里的getSingleton方法,注意这个getSingleton和上面代码块8的不是一个方法:

代码块10.10

                                                                代码块24
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "'beanName' must not be null");
		synchronized (this.singletonObjects) {
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				// 如果当前beanFactory处在destruction状态中,则不允许创建bean
				// 这个状态指的是beanFactory执行了destroySingletons方法,即applicationContext执行close方法会调用到这个方法
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while the 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 + "'");
				}
				// 1. 创建单例前的检查
				beforeSingletonCreation(beanName);
				// suppressedExceptions用户记录在创建期间出现的异常
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<Exception>();
				}
				try {
					// 调用ObjectFactory来创建bean
					singletonObject = singletonFactory.getObject();
				}catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					// 2. 创建单例后的检查
					afterSingletonCreation(beanName);
				}
				// 将创建出来的bean放到缓存中
				addSingleton(beanName, singletonObject);
			}
			return (singletonObject != NULL_OBJECT ? singletonObject : null);
		}
	}

我们来看上面的代码块中1,创建单例前的检查:

                                                                代码块25
        protected void beforeSingletonCreation(String beanName) {
		// 检查bean是否要包含在检查已经创建的集合中,如果不是,则看bean是否在创建中
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

然后是代码块24中的2,创建单例后的检查:

                                                                代码块26
        protected void afterSingletonCreation(String beanName) {
		// 检查bean是否要包含在检查已经创建的集合中,如果不是,则从正在创建的集合中移除,
		// 移除失败则抛异常
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}

getSingleton方法完了,我们继续回到代码块10看11处的创建prototype前的检查:

代码块10.11

                                                                代码块27
        @SuppressWarnings("unchecked")
	protected void beforePrototypeCreation(String beanName) {
		// 从当前线程正在创建的prototype中拿所有的正在创建的集合
		Object curVal = this.prototypesCurrentlyInCreation.get();
		// 如果curlVal是空,则设置当前bean为正在创建的bean
		if (curVal == null) {
			this.prototypesCurrentlyInCreation.set(beanName);
		// 如果不是空并且是个String(代表有一个在创建中),则创建集合,并且把curVal
		// 和当前beanName都加进去
		} else if (curVal instanceof String) {
			Set<String> beanNameSet = new HashSet<String>(2);
			beanNameSet.add((String) curVal);
			beanNameSet.add(beanName);
			this.prototypesCurrentlyInCreation.set(beanNameSet);
		// 这种的说明是有两个以上的在创建,直接加入正在创建的集合中去
		} else {
			Set<String> beanNameSet = (Set<String>) curVal;
			beanNameSet.add(beanName);
		}
	}

接下来是代码块10看12处:

代码块10.12

                                                                代码块29
        @SuppressWarnings("unchecked")
	protected void afterPrototypeCreation(String beanName) {
		// 获取正在创建的prototype的集合
		Object curVal = this.prototypesCurrentlyInCreation.get();
		// 如果是String则直接remove掉
		if (curVal instanceof String) {
			this.prototypesCurrentlyInCreation.remove();
		}
		// 如果是set则从set中删除
		else if (curVal instanceof Set) {
			Set<String> beanNameSet = (Set<String>) curVal;
			beanNameSet.remove(beanName);
			if (beanNameSet.isEmpty()) {
				this.prototypesCurrentlyInCreation.remove();
			}
		}
	}

至此doGetBean方法已经讲完,下一篇,我们开始createBean方法