对于bean的加载,Spring 的调用方式为

Bean2 bean = (Bean2)context.getBean("bean2");

无论使用何种方式,ApplicationContext还是过时的XmlBeanFactory都调用的是AbstractBeanFactory的默认实现getBean方法

public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

getBean又委托给了doGetBean,我们从上到下来解析一下

protected <T> T doGetBean(w
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
				/**
		 * 为什么要取得beanName,name不是beanName吗?
		 * name其实可以为很多值: id,alias,factoryBean等
		 * transformedBeanName可以通过name放回唯一对应bean的beanName
		 * */
		final String beanName = transformedBeanName(name);
		Object bean;
		//尝试从缓存中或者ObjectFactory中获取
		Object sharedInstance = getSingleton(beanName);

在分析getSingleton方法之前有必要在说下FactoryBean的使用,通常我们配置bean的时候一般是这么配置

<bean id="fristBean" class="spring.demo.FristBaen" name="fe,fef">
		</bean>

而使用FactoryBean的配置

<bean id="fristBeanFactory" class="spring.demo.FristBaenFactory">
		</bean>

FristBaenFactory需要实现FactoryBean这个接口,需要实现它的3个方法getObject() 返回值为真正需要的bean实例,isSingleton()返回值为true则为单例否则就是原型 getObjectType返回FactoryBean创建实例的类型。当getBean调用fristBeanFactory时,会通过反射获取到实现了FactoryBean,就会默认调用getObject方法返回实例,如果isSingleton返回true则放入单例缓存。当需要取得fristBeanFactory实例时就需要在getBean的参数前加上&如getBean("&fristBeanFactory")。好了FactoryBean先说到这里,下面进入到getSingleton中

public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}

再次调用了它的重载方法参数多了一个true允许早期的循环依赖

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		
		//singletonObjects是一个Map集合,里面存储着已经加载过的bean
		Object singletonObject = this.singletonObjects.get(beanName);
		//如果缓存里面 ,并且有用户正在创建该bean,正在创建的bean会被存储到singletonsCurrentlyInCreation这个map中,
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			
			//加锁,防止并发问题                   
			synchronized (this.singletonObjects) {
				
				//从earlySingletonObjects中取,如果
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					//取得的是beanFactory里的缓存
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						//bean工厂有就取得实例
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}

以上这段琢磨了半天,最后结合循环依赖的解决方式才明白过来。那我们先来看看循环依赖以及解决方式,
我们bean有自己创建实例以及属性注入的功能,循环依赖就发生在属性注入的时候,比如bean A中有一个B类型的属性,B中又有一个A类型的属性,这将在创建A实例的时候去取B实例,B实例创建的时候又要A实例,这就陷入死循环了。那如何解决呢?我们知道bean的属性注入有两种方式,构造方法注入,以及set方法注入,构造方法注入创建实例之前必须明确的指定实例,所以构造方法注入遇到循环依赖无解,会直接抛出个异常出来了。而set方法的解决方法官方叫做提前暴露,就是说把创建对象与属性注入分来,先创建对象再进行属性注入,这样A实例有l,B实例也有了在进行属性注入。
明白了这个我们回到getSingleton方法中,singletonObjects这个map存储的是已经全部完成的bean,也就是实例有了属性也注入了的完整bean。earlySingletonObjects存储的是有实例但并没有属性注入的bean。那么获取缓存逻辑就顺畅了,先获取完整的bean,没有的话从earlySingletonObjects中取,因为有可能有别的用户再创建bean但没有完成也就是没有注入属性。都没有的话就从beanFactory中取出了,beanFactory存储的是已经加载好了bean但还没有实例化的bean也就是有用户再创建bean但还没到实例化的时候。所以有缓存的话返回值有两种状态,要么是bean实例并且属性全部注入了,要么只是bean实例而没有注入属性,所以还要对返回值做进一步处理。
注 : getSingleton方法也恰好说明了原型不能解决循环依赖。所有提前暴露的实例都存储在key为beanName的map集合中,我们都知道key相同value会被覆盖,这将导致原型注入的都是最后存储在map中的实例。

以上通过getSingleton方法尝试取出缓存,完成后分为两种情况,有缓存和无缓存,我们分别分析

//再缓存中取得实例,并且有参数的情况下
		if (sharedInstance != null && args == null) {
			//名字就叫做通过bean实例获取对象。。。
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

以上这段就是从缓存中取出并且没有参数的情况下,调用getObjectForBeanInstance返回真正需要的bean实例

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

		// 如果指定的name包含了&符但是bean实例类型又不是FactoryBean则抛出异常
		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}

		//如果bean类型不是factoryBean或者name是&符(用户需要beanFactory实例)
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

		//需要从factoryBean中取得bean的情况
		
		Object object = null;
		if (mbd == null) {
			//从缓存中加载bean
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// 向上转型,明确的表示为factoryBean
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			//如果是子bean将合并父类的相关属性
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//处理factoryBean 取得实例
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

getObjectForBeanInstance 对于非FactoryBean和只获取FactoryBean本身实例的情况不做处理,只处理通过FactoryBean获取bean实例又委托给了getObjectFromFactoryBean

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) {
					//取得object
					object = doGetObjectFromFactoryBean(factory, beanName);

					//再次判断缓存中是否存在,存在取缓存中值,不存在加入缓存
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						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);
							}
						}
						//加入缓存
						this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
					}
				}
				return (object != NULL_OBJECT ? object : null);
			}
		}
		else {
			//取得object
			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;
		}
	}

getObjectFromFactoryBean只做了一个判断,如果FactoryBean返回单例bean就尝试从缓存中取出,判断是否是单例bean正如我们上面讲述的一样,是我们自己重写FactoryBean的isSingleton方法。如果没有缓存或者配置的是原型name都调用postProcessObjectFromFactoryBean方法返回

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

		Object object;
		try {
			//配置了权限管理器,要进行权限验证,否则直接取出Object
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						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);
		}

		// Do not accept a null value for a FactoryBean that's not fully
		// initialized yet: Many FactoryBeans just return null then.
		if (object == null && isSingletonCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(
					beanName, "FactoryBean which is currently in creation returned null from getObject");
		}
		return object;
	}

上面这段就很简单了直接调用了FactoryBean的getObject() 返回,这个方法就是我们自己实现的,没什么可说的。

好了,通过以上代码我们就可以获取到单例缓存中的bean或者是通过FactoryBean获取的bean。我们继续往下走,创建单例bean或者原型bean

//只会再单例情况下尝试去处理循环依赖,原型直接抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 使用parentBeanFactory创建bean得情况
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//如果存在beanFactory并且当前bean定义中未注册beanName
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// 从beanFactory取得实例
				String nameToLookup = originalBeanName(name);
				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);
				}
			}

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

这里的isPrototypeCurrentlyInCreation判断是否是原型并且是否包含了循环依赖,那么它是怎么实现的呢?其实它使用了ThreadLocal的思想,关于ThreadLocal可以查看ThreadLocal,ThreadLocal存储着一个set,set里面存储着当前线程加载的所有原型bean,再加载原型bean准备工作的时候就会把所有的beanName存储在set中也就是ThreadLocal中,当完成了bean的加载时候又会根据beanName从set中删除掉。那么当一个请求(一个线程)进行创建bean的时候,ThreadLocal中有这个beanName时,必定存在着循环依赖。如例子 : Bean A 持有着Bean B,Bean B又持有着Bean A,当创建bean A时把beanAName放置再set中,接着创建beanB的时候又需要创建beanA,但第一次创建beanA还并没有结束,所以判断set中包含了beanAname,存在着循环依赖。

//取得beanDefinition
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// 保证依赖的bean都初始化
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dependsOnBean : dependsOn) {
						getBean(dependsOnBean);
						registerDependentBean(dependsOnBean, beanName);
					}
				}

				// 如果配置的是单例
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						public Object getObject() throws BeansException {
							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);
				}

以上是一段取出单例bean的逻辑,调用了重载方法getSingleton(beanName,ObjectFactory)来创建单例bean

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "'beanName' must not be null");
		//共享元素当然得加锁
		synchronized (this.singletonObjects) {
			//从缓存中取出,很多方法是public的,所以得判断缓存很多次
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				//把beanName存储在map中,用于判断构造方法创建bean实例时得循环依赖问题
				beforeSingletonCreation(beanName);
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<Exception>();
				}
				try {
					//从ObjectFactoy中取得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;
					}
					//从循环依赖集合删掉指定的beanName
					afterSingletonCreation(beanName);
				}
				//取得了bean,缓存加上
				addSingleton(beanName, singletonObject);
			}
			return (singletonObject != NULL_OBJECT ? singletonObject : null);
		}
	}

getSingleton方法只做了添加,删除特定缓存的功能,它把创建bean实例的功能回调了ObjectFactory的getObject方法。ObjectFactory调用createBean来取得实例,createBean实现在AbstractBeanFactory的子类AbstractBeanFactory中。

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		//解析bean的class
		resolveBeanClass(mbd, beanName);

		// 验证及准备覆盖的方法,如在spring里面配置的lookup-method和replace-method
		try {
			mbd.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 返回代理实例
			Object bean = resolveBeforeInstantiation(beanName, mbd);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		//调用doCreateBean取得实例
		Object beanInstance = doCreateBean(beanName, mbd, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

创建bean时首先会根据设置的class属性来解析class ,然后处理override也就是bean标签配置了lookup-method或者replace-method,

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
		// 检查是否配置了lookup-method或者是replace-method
		MethodOverrides methodOverrides = getMethodOverrides();
		if (!methodOverrides.isEmpty()) {
			for (MethodOverride mo : methodOverrides.getOverrides()) {
				prepareMethodOverride(mo);
			}
		}
	}
	protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
		
		int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
		if (count == 0) {
			throw new BeanDefinitionValidationException(
					"Invalid method override: no method with name '" + mo.getMethodName() +
					"' on class [" + getBeanClassName() + "]");
		}
		else if (count == 1) {
			// Mark override as not overloaded, to avoid the overhead of arg type checking.
			mo.setOverloaded(false);
		}
	}

乍一看有点摸不着头脑,在spring配置中lookup-method和replace-method都会存储在methodOverride属性中,再解析bean的时候,通过代理来动态的为bean做增强处理,但是再这里并没有对methodOverride里的value做代理操作啊。其实这里只做了检查,我们知道再lookup-method中配置的方法可能存在着重载的情况,当设置的name没有命中相关bean的方法时,将抛出BeanDefinitionValidationException异常,如果只有一个与之对应的方法名,就设置是否重载为false。当然默认为true

接下来如果代理创建了bean就直接返回了,关于这代理类部分我们以后分析,再没有代理类的情况下我们就需要自己来创建bean实例了。

创建bean的方法doCreateBean辑较复杂,我们从前到后依次分析

BeanWrapper instanceWrapper = null;
		
		//如果是单例,尝试从工厂缓存中取出
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//使用特定的策略来创建bean,如: 工厂方法,构造函数自动调用,简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

这里有一个BeanWrapper的对象,它可以说时bean的前身,并不是一个完整的bean还没有属性注入。BeanWrapper本身也提供着属性注入的功能。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, 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());
		}

		//如果配置了Factory-mehtod等属性,则使用工厂方法初始化
		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 匹配构造函数,根据参数找到特定的构造初始化bean
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 (beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

		// Need to determine the constructor...
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);
	}

取得bean实例无非就两种情况,工厂取得,自己调用构造实例化。构造方法可能有着不同的参数,Spring 花了大量的篇幅根据参数个数,类型去定位到具体的构造方法,取得构造方法后看它是否配置了lookup-method或者replace-method,如果未配置直接用反射取得实例,配置了就需要用cglib等代理取增强方法了。这里不再赘述,以后单独分析。