Spring bean的生命周期,对比源码详解

    为了更加熟悉spring的总体流程,看了spring的源码。

    看了很多网上的资料写的spring的bean的生命周期,但是感觉和看到的源码有部分出入,这里再总结下。

 

正文:    

 

spring获取bean的时候有两种方式:

    BeanFactory bf  = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

    Object t = bf.getBean("myBean");

    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

    Object t = ac.getBean("myBean");

    

   这篇文章先看第一种方式,使用beanFactory加载bean并获取

   new ClassPathResource("applicationContext.xml") 这句话是加载资源文件的,主要是把配置文件映射到spring的配置文件对象Resource中,逻辑比较多,这里我们不关注,有兴趣的同学可以自行学习

  当获取到resource后我们进入加载XmlBeanFactory的逻辑,我们只关注主线,如何获取bean(即getBean("mybean")方法)。跟踪代码,我们发现了这样的继承关系:

XmlBeanFactory <-- DefaultListableBeanFactory <--AbstractAutowireCapbleBeanFactory <-- AbstractBeanFactory  

在 AbstractBeanFactory中我们找到了getBean(“”)的方法调用。下边是代码,我写了些注释帮助理解

public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
		//获取对应的beanname
		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		/**
		 * 检查缓存中或者实例工厂中是否有对应的bean
		 * 为什么首先会使用这段代码呢?
		 * 因为在创建单例bean的时候会存在依赖注入的情况,而创建依赖的时候为了避免循环依赖
		 * Spring创建bean的原则是不等bean创建完成就将创建bean的ObjectFactory提早曝光
		 * 也就是将ObjectFactory加入缓存,一旦下一个bean创建的时候需要依赖上一个bean的时候直接使用objectFactory
		 * 
		 */
		//直接尝试从缓存中获取,或者singletonfacotory中获取
		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 + "'");
				}
			}
			//返回对应的实例,有时候存在诸如beanFactory的情况并不是直接返回实例本身,而是返回指定方法返回的实例
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			//只有在单例情况才会尝试解决循环依赖。原型模式下如果存在A中有b,b中有A,
			//那么当依赖注入的时候就会产生当A还未创建完的时候对于B的创建再次返回创建A
			//造成循环依赖 也就是下面的情况
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//如果beanDefinitionMap中也就是已经加载的bean类中不包括beanName,则尝试从parentbeanfactory中获取
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (args != null) {
					//递归到parentFacotory中寻找
					// 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);
				}
			}
			//如果不是仅仅做类型检查而是创建bean这里要进行记录
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}
			//将存储XML配置文件的GericBeanDefinition转换为RootBeanDefinition,如果指定Beanname是子类的话会同时合并父类的相关属性
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			//若存在依赖则要递归实例化依赖的bean
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) {
					getBean(dependsOnBean);
					//缓存依赖调用
					registerDependentBean(dependsOnBean, beanName);
				}
			}

			// Create bean instance.
			//实例化依赖的bean后就可以实例化mdb本身了
			//singleton模式的创建
			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);
			}
			//prototype的创建(new)
			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
			//指定scope上的实例化
			else {
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
						public Object getObject() throws BeansException {
							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);
				}
			}
		}
		//检查需要的类型是否符合bean的实际类型
		// Check if required type matches the type of the actual bean instance.
		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;
	}

上面的逻辑比较多,其实有这么几个事情大家需要知道的(我们先重点关注singleaton策略,原生的不关注)。

 

  1. spring在生成bean的时候其实是先生成一个创建bean的工厂,一般情况(即普通类)是一个ObjectFactory的工厂类来生成bean。
  2. 生成的这个factoryBean在生成之后并没有完事,还需要把这个工厂放到缓存中以备后续其他的bean用的这个bean的时候直接调用工厂获取bean,其实工厂生成的bean也已经存到缓存中,当其他bean需要这个bean的时候直接调用工厂生成bean,如果已经生成了,工厂会直接从缓存中拿出这个bean。(很多同学想不通为什么spring要搞个工厂来生成bean,直接存bean不就好了,其实是因为spring需要解决bean质检的循环依赖才引入的,A->B->C->A 感兴趣的同学可以自行研究,这里我们跳过,只关注主线逻辑。

 

通篇看一遍上面的代码,给bean赋值的只有这个方法了,我们进去看看

 

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
		//如果指定的name是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型验证不通过
		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		//现在我们有个bean的实例,这个实例可能是bean或者是beanFactory的实例
		//如果是FacotryBean我们使用它创建bean,但是如果用户想要获取工厂实例而不是工厂的getObject方法对应的实例那么传入的name应该加入前缀&
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}
		//加载FactoryBean
		Object object = null;
		if (mbd == null) {
			//尝试从缓存中加载bean
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			//这一已经知道实例一定是beanFactory类型的
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				//将存储xml配置的GenricBeanDefinition转换为rootbeanDefinition,如果指定beanName是子类的话同时会合并父类的相关属性
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			//是否是用户定义的不是应用程序本身定义的
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

上面的代码我们又这么几个事情需要知道

 

  1. 初始化一个bean我们有三种方案 (1)简单初始化(就是什么都不管,直接调用bean的空创建方法进行初始化)(2)带参初始化(就是我们需要在spring配置文件中指定参数,我想大家都应该见过)(3)自定义工厂方式初始化
  2. 针对上面的自定义工厂方式我估计很多同学没有怎么用过,多说一些,平常我们在spring中会这样定义一个bean
<bean id="testListener" class="test.beans.TestListener"></bean>

       其实我们还可以定义一个FacotryBean来控制生成的bean,前提是我们的bean需要实现FactoryBean<T>接口,像这样

public class TestFactoryBean implements FactoryBean<Test>{

	public Test getObject() throws Exception {
		
		return new Test();
	}

	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return null;
	}

	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return false;
	}

}

然后我们在配置文件里只需要修改bean定义的class为我们新建的factory就可以了

 

<bean id="testListener" class="test.beans.TestFactoryBean"></bean>

  上面的如果采用了自定义方式的factory类生成bean,其实我们可以通过在类名前加“&”符号的方式来获取他,像这样

 
TestFacotryBean ttb = (TestFactoryBean)getBean("&testListener")

-------------------------------------------------------------------------------------------------------------------------

好我们接着看下面的逻辑,这个方法里我们发现先是从缓存中获取bean,没有的话再往下走,我们分析的是第一次加载,肯定是要往下走了,分析这个方法

 

object = getObjectFromFactoryBean(factory, beanName, !synthetic);

 

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 = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
					this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
				}
				return (object != NULL_OBJECT ? object : null);
			}
		}
		else {
			return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
		}
	}

在上面的方法中所有的bean赋值都指向了这个方法,接着跟进

doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(
			final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
			throws BeanCreationException {

		Object object;
		try {
			//需要权限验证
			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 {
				//直接调动getObject方法
				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");
		}

		if (object != null && shouldPostProcess) {
			try {
				//调用objectFactory的后处理器
				object = postProcessObjectFromFactoryBean(object, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);
			}
		}

		return object;
	}


上面的方法里我们看到最核心的一句话

 

//直接调动getObject方法
				object = factory.getObject();

这里我们才知道,原来获取bean获取到最后我们还是需要从我们开始定义的FactoryBean中才能找到答案,就和我刚开始解释的一样,spring所有的bean生成都委托给我factoryBean类。这也是为什么我在上面要专门讲一下自定义生成bean的方式了,这样才能帮助理解。

--------------------------------------------------------------------------------------------------------------

好了,我们接着看看factoryBean中到底搞了什么事情,依次反查这个方法的调用,找到factoryBean最开始设置的地方,我们找到了这里

// Create bean instance.
			//实例化依赖的bean后就可以实例化mdb本身了
			//singleton模式的创建
			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);
			}

定位到createBean方法

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

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		// Make sure bean class is actually resolved at this point.
		//锁定class,根据设置的class属性或者根据classname来解析class
		resolveBeanClass(mbd, beanName);

		// Prepare method overrides.
		//验证及准备覆盖的方法
		try {
			mbd.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			//给BeanPostProcessors一个机会来返回一个代理类类来替换真正的实例
			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);
		}

		Object beanInstance = doCreateBean(beanName, mbd, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

上面的方法中有个很重要的地方我必须要说一下,虽然和我们的主线没什么关系就是这句话。

 

try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			//给BeanPostProcessors一个机会来返回一个代理类类来替换真正的实例
			Object bean = resolveBeforeInstantiation(beanName, mbd);
			if (bean != null) {
				return bean;
			}
		}

在这个函数下面调用doCreateBean之前,调用了个resolveBeforeInstantiation方法,还返回了个bean,并且这个bean不为空的话直接返回,后面的逻辑都不走了,大家可以想想原因。这就是著名的AOP实现的地方,这里是非常重要的代码,resolveBeforeInstantiation中通过AOP制定的代理类生成一个新的bean,这里监控到bean被改变了就直接返回新的代理类了。

 

好,闲话不多说,接着走发现了这个方法

 

Object beanInstance = doCreateBean(beanName, mbd, args);

其实Spring的代码核心的都是doxxxxxx(),其他的都是组织代码结构的。进去看看。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//根据指定bean使用对应的策略创建新的实例,如:工厂方法,构造函数自动注入,简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				//利用MergedBeanDefinitionPostProcessors
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		//是否需要提早曝光:单例&允许循环依赖&当前bean正在创建,检测循环依赖
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
			addSingletonFactory(beanName, new ObjectFactory() {
				
				public Object getObject() throws BeansException {
					//对bean再一次依赖引用,主要应用SmartInstatiantionAware BeanPostProccessor
					//其中我们熟悉的AOP就是在这里将advice动态织入的,若没有则直接返回bean不做任何处理
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				//调用初始化方法,比如init-method
				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);
			//earlySingletonReference 只有检测到有循环依赖的情况下才会不为空
			if (earlySingletonReference != null) {
				//如果exposedObject没有被改变也就是没有被增强
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						//检测依赖
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					/**
					 * 因为bean创建后,其依赖的bean一定是已经创建的
					 * actualDependentBeans不为空标识当前bean创建后其依赖的bean却没有创建完成。也就是说存在循环依赖
					 */
					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 {
			//根据scope注册bean
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

上面看的有点多,我们需要知道的有这几个

 

  1. spring在加载完配置文件后会把这个bean的定义放到佳作RootBeanDefinition的类中保存起来,之后方法调用传参也用这个类,包括属性的保存等等
  2. 然后通过RootBeanDefinition生成了一个beanWrapper的类,这个类中包含了我们的bean,和bean的属性的描述信息
  3. 而我们需要的其实只是beanWrapper中的bean

好了,这次思路比较清晰,先生成一个beanWrapper,然后获取其中的bean就好了

看第一个生成beanWrapper的方法

if (instanceWrapper == null) {
			//根据指定bean使用对应的策略创建新的实例,如:工厂方法,构造函数自动注入,简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

进去

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// Make sure bean class is actually resolved at this point.
		//解析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());
		}
		//如果工厂方法不为空则使用工厂方法初始化策略
		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same 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 autowireConstructor(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);
	}

上面的代码看看结构,大概分为三个逻辑

 

  1. 有工厂方法的用工厂方法初始化(同学们不要看错了,这里是工厂方法,不是工厂类,spring中可以通过factory-method标签指定生成当前类的方法的)
  2. 有参数的用参数初始化(这里有个构造方法缓存的问题,我们不讨论)
  3. 没有参数的调用默认的构造函数初始化

接着跟进只看默认构造函数

 

//使用默认的构造函数
		return instantiateBean(beanName, mbd);

 

	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					public Object run() {
						return getInstantiationStrategy().instantiate(mbd, beanName, parent);
					}
				}, getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

看到这句话,接着跟进

 

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

 

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (beanDefinition.getMethodOverrides().isEmpty()) {
			Constructor<?> constructorToUse;
			synchronized (beanDefinition.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class clazz = beanDefinition.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
								public Constructor run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Exception ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(beanDefinition, beanName, owner);
		}
	}

 

这里大家也许很疑惑为什么跑出一个

if (beanDefinition.getMethodOverrides().isEmpty()) {

其实我们在定义bean的时候有个功能很少用到,就是replace-method 和 lookup-method方法,我们在配置文件中用了这两个方法后就能直接替换原始bean的任何一个方法的实现,但前提是我们要使用cglib,因为这里需要使用动态代理替换实现类为代理类

上面的方法终于看到了我们需要的代码,从这个方法进去就能看到通过构造方法生成类的方法了,关注下当前到了哪个类里了,是个叫做SimpleInstantiationStragety的类,这个类是实现了InstantiationStrategy类,也是唯一的实现类。这说明所有的简单初始化操作我们都是走的这个类。

return BeanUtils.instantiateClass(constructorToUse);

兄弟们不要着急,到现在为止我们只是创建了一个bean,里边的属性还都没设置呢,回到之前的doCreateBean方法,

 

try {
			//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				//调用初始化方法,比如init-method
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}

上面的属性注入过程我们进去看看

protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
		PropertyValues pvs = mbd.getPropertyValues();

		if (bw == null) {
			if (!pvs.isEmpty()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				//没有可以填充的属性
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		//给instantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean
		//如:可以用来支持属性注入的类型
		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;
					}
				}
			}
		}
		//如果后处理器发出停止命令则终止后续执行
		if (!continueWithPropertyPopulation) {
			return;
		}

		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			//根据名称自动注入
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// Add property values based on autowire by type if applicable.
			//根据类型自动注入
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}
		//后处理器已经初始化
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		//需要减产依赖
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						//对所有需要检查依赖的属性进行后处理
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				//回来检查 对应depends-on属性,3.0已经弃用此属性
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
		//将属性应用到bean中
		applyPropertyValues(beanName, mbd, bw, pvs);
	}

上面的逻辑主要分为这几项

 

  1. 通过后处理器来控制属性是否继续填充(这里我们先不关注)
  2. 通过byType或者byName的方式获取属性值
  3. 将属性值应用到beanWrapper中

重点在这里

 

if (exposedObject != null) {
				//调用初始化方法,比如init-method
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}

看看这个方法里面做了什么

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			//对特殊的bean处理:aware、BeanClassLoaderAware,beanFactoryAware
			invokeAwareMethods(beanName, bean);
		}
		
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//应用后处理器
			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()) {
			//后处理器应用
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}

上面的代码主要分为三块逻辑,设置beanWare,初始化bean,调用后处理器的处理方法。

我们需要知道这么几个事情

 

  1. 一般情况下其实我们不需要关注我们的bean生成过程中到底用了什么类加载器,用的是哪个工厂做的操作(如果不是我们自定义的话),如果想要知道该怎么办呢?spring给我留了方法,就是让bean去实现ware接口,需要name的话实现BeanNameAware,需要类加载器则实现BeanClassLoaderAware,需要bean工厂,则实现BeanFactoryAware,所以这里有一步是设置相应ware需要的对应资源的。
  2. spring在控制bean生成的时候留了很多扩展功能接口,后处理器(beanPostProcessor)就是其中之一,如果我们想要在bean生成的前后做一些事情,比如打日志,写入新的属性之类的,都可以通过beanPostProcessor来设置。但是我们貌似通篇也没有看到到底在哪里设置了beanPostProcessor。其实通过beanFacotry方式获取bean的时候spring把添加后处理器的方法交给了我们。我们可以这样做:
DefaultListableBeanFactory bf  = new XmlBeanFactory(new ClassPathResource(""));
		bf.addBeanPostProcessor(beanPostProcessor);

这样就添加了一个beanPostPorcessor

恩,上面还有一个逻辑是初始化逻辑,就是调用配置文件中配置的init-method方法,我们梳理下整个逻辑

 

  1. 如果bean实现了aware方法,则先处理aware方法的实现方法
  2. 如果存在后处理器,则调用后处理器的postProcessBeforInitialization方法
  3. 调用bean的init-method方法
  4. 如果存在后处理器,则调用后处理器的postProcessAfterInitialization方法

后面还有一点逻辑,就是下面这段代码

try {
			//根据scope注册bean
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}

进去看看

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
		AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
		if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
			if (mbd.isSingleton()) {
				// Register a DisposableBean implementation that performs all destruction
				// work for the given bean: DestructionAwareBeanPostProcessors,
				// DisposableBean interface, custom destroy method.
				/**
				 * 单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean
				 */
				registerDisposableBean(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
			else {
				// A bean with a custom scope...
				Scope scope = this.scopes.get(mbd.getScope());
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");
				}
				scope.registerDestructionCallback(beanName,
						new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
			}
		}
	}

这里是注册销毁bean的逻辑,这里涉及到spring的后置处理器,beanPostProcessor的东西,暂时不考虑,总之就是要销毁这个bean,并销毁他所占用的缓存等资源(像之前说的beanFactory缓存,bean缓存等等)

现在我们再说说原型模式的获取方式,在我们刚开始的函数doGetBean方法中,有这样的方法

	//singleton模式的创建
			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);
			}
			//prototype的创建(new)
			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);
			}

对比看看这个if else。if里的逻辑是单例singleaton,else里是prototype原型。

发现了:其实单例方式只是比原型方式多了一个objectFacotry。也就是说,单例必须先弄个objectFactory,然后再通过objectFacotry去生成bean才行;而原型模式直接createBean();就能创建,后边的逻辑一样,到了abstractAutoWireCapableBeanFactory中的doCreateBean();方法,利用SimpleInstantiationStragety创建bean,然后注入属性,然后注册销毁,然后返回。

---------------------------------------------------------------------------------------------------------------------------------

总结下:

我们到目前为止说的都是通过beanFacotry生成bean的逻辑,也就是两种方式中的一种(另外一种是xmlApplicationContext)。

看到其他一些资料里说spring的bean生成核心类是DefaultListableBeanFacotry,其实我感觉更像是AbstractAutowireCapableBeanFactory,因为核心的doCreate()方法是在这里实现的。里面交代了bean会在这里利用SimpleInstantiationStragety类进行简单初始化,并在doCreateBean方法中完成对属性的注入,到这里完成了所有beanWrapper类的装配,然后又获取beanWrapper中的bean类型,对bean添加了aware和postProcess的处理逻辑,然后又在这里完成了对bean销毁方式的注册。然后层层返回之后就是getBean(“myBean”)得到的结果了。

总结步骤:

 

  1. 利用SimpleInstantiationStragety进行初始化(可以是工厂方式的,也可以是单参数形式的,也可以是无参数的简单初始化),结果是我们得到了一个实例,但是属性都是空的
  2. 进行属性的注入,这里分别通过byName或者byType获取属性信息,并递归调用getBean方法获取属性bean
  3. 根据bean实现的aware接口调用相应的aware方法设置资源(beanNameAware,BeanClassLoaderAware,BeanFactoryAware)
  4. 如果实现了后处理器BeanPostProcessor,则遍历后处理器调用postProcessBeforeInitialization方法处理逻辑
  5. 调用用户自定义的init-method方法
  6. 如果实现了InitializingBean接口则调用afterPropertiesSet方法,这个方法只会在所有属性都被设置的时候才会触发
  7.  如果实现了后处理器BeanPostProcessor,则遍历后处理器调用postProcessAfterInitialization方法处理逻辑
  8. bean可以使用了

 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值