Spring源码解析(二):容器的其他相关特性

上一篇中对IOC容器的主要功能进行了分析,比如Bean的载入以及解析,依赖注入的实现等,这一篇中会对容器的其他相关特性也进行分析,这些特性都是我们在使用容器是会经常遇到的。

一.Bean的生命周期

首先简单介绍一下bean的生命周期

1.bean实例的创建

2.为bean的实例注入属性

3.调用Bean的初始化方法

4.应用可以通过IOC容器使用bean

5.容器关闭时,调用bean的销毁方法

Bean实例的创建以及注入的过程在上一篇已经分析过,我们主要来看看Bean的初始化方法的调用过程,这个过程是在AbstractCapableBeanFactory的initializeBean方法中实现的,方法代码如下:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
                //执行bean的一系列Aware方法(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>(){
				@Override
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
                //如果bean实现了BeanPostProcessor,执行postProcessBeforeInitialization方法
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}
                //如果bean实现了InitializingBean接口,调用它的afterPropertiesSet方法,然后调用Bean的init-Mehthod方法
		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
                //如果bean实现了BeanPostProcessor,执行postProcessAfterInitialization方法
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}

然后我们再来看一看Bean的销毁的过程, 当我们需要关闭容器时,可以通过容器的destroy方法或close方法来销毁容器,销毁容器的过程的具体的实现是在AbstractApplicationContext的doClose方法中,方法方法代码如下:

protected void doClose() {
		if (this.active.get() && this.closed.compareAndSet(false, true)) {
			if (logger.isInfoEnabled()) {
				logger.info("Closing " + this);
			}

			LiveBeansView.unregisterApplicationContext(this);

			try {
				// 发布容器关闭事件
				publishEvent(new ContextClosedEvent(this));
			}
			catch (Throwable ex) {
				logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
			}

			
			try {
				getLifecycleProcessor().onClose();
			}
			catch (Throwable ex) {
				logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
			}

			//销毁bean
			destroyBeans();

			// 关闭容器
			closeBeanFactory();

			// 这个方法留给子类实现,子类可以定制销毁容器时的一些操作
			onClose();

			this.active.set(false);
		}
	}
protected void destroyBeans() {
		getBeanFactory().destroySingletons();
	}
public void destroySingletons() {
		super.destroySingletons();
		this.manualSingletonNames.clear();
		clearByTypeCache();
	}
public void destroySingletons() {
		if (logger.isDebugEnabled()) {
			logger.debug("Destroying singletons in " + this);
		}
		synchronized (this.singletonObjects) {
			this.singletonsCurrentlyInDestruction = true;
		}
                //遍历销毁所有需要销毁的bean
		String[] disposableBeanNames;
		synchronized (this.disposableBeans) {
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
		}
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
			destroySingleton(disposableBeanNames[i]);
		}
                //清空相关的缓存
		this.containedBeanMap.clear();
		this.dependentBeanMap.clear();
		this.dependenciesForBeanMap.clear();

		synchronized (this.singletonObjects) {
			this.singletonObjects.clear();
			this.singletonFactories.clear();
			this.earlySingletonObjects.clear();
			this.registeredSingletons.clear();
			this.singletonsCurrentlyInDestruction = false;
		}
	}

销毁bean的具体实现在destroySingleton方法中

public void destroySingleton(String beanName) {
		//清除当前bean的相关的缓存
		removeSingleton(beanName);

		//销毁bean,这里的disposableBean是一个DisposableBeanAdapter的实例
		DisposableBean disposableBean;
		synchronized (this.disposableBeans) {
			disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
		}
		destroyBean(beanName, disposableBean);
	}
protected void destroyBean(String beanName, DisposableBean bean) {
                //递归的销毁所有的依赖bean
		Set<String> dependencies = this.dependentBeanMap.remove(beanName);
		if (dependencies != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
			}
			for (String dependentBeanName : dependencies) {
				destroySingleton(dependentBeanName);
			}
		}

		//这个bean是一个DisposableBeanAdapter的实例,执行对bean的销毁处理
		if (bean != null) {
			try {
				bean.destroy();
			}
			catch (Throwable ex) {
				logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
			}
		}

		//递归的销毁当前所包含的内部的bean
		Set<String> containedBeans = this.containedBeanMap.remove(beanName);
		if (containedBeans != null) {
			for (String containedBeanName : containedBeans) {
				destroySingleton(containedBeanName);
			}
		}

		// 移除其他依赖当前bean的依赖关系
		synchronized (this.dependentBeanMap) {
			for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
				Map.Entry<String, Set<String>> entry = it.next();
				Set<String> dependenciesToClean = entry.getValue();
				dependenciesToClean.remove(beanName);
				if (dependenciesToClean.isEmpty()) {
					it.remove();
				}
			}
		}

		// Remove destroyed bean's prepared dependency information.
		this.dependenciesForBeanMap.remove(beanName);
	}

下面看看DisposableBeanAdapter中的destroy方法的实现

public void destroy() {
                //首先对postProcessBeforeDestruction进行调用
		if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
			for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
				processor.postProcessBeforeDestruction(this.bean, this.beanName);
			}
		}
                //如果实现了DisposableBean接口,调用bean的destroy方法
		if (this.invokeDisposableBean) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
			}
			try {
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
							((DisposableBean) bean).destroy();
							return null;
						}
					}, acc);
				}
				else {
					((DisposableBean) bean).destroy();
				}
			}
			catch (Throwable ex) {
				String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
				if (logger.isDebugEnabled()) {
					logger.warn(msg, ex);
				}
				else {
					logger.warn(msg + ": " + ex);
				}
			}
		}
                //调用用户自定义的destroy-method方法
		if (this.destroyMethod != null) {
			invokeCustomDestroyMethod(this.destroyMethod);
		}
		else if (this.destroyMethodName != null) {
			Method methodToCall = determineDestroyMethod();
			if (methodToCall != null) {
				invokeCustomDestroyMethod(methodToCall);
			}
		}
	}

整个bean的生命周期的分析到这里就结束了

二、Bean的lazy-init属性

在上一篇Spring源码解析(一):Spring的IOC实现中分析依赖注入的过程时说过,如果bean为singleton并且未配置lazy-init属性(默认为false),那么会在初始化容器时,在解析载入BeanDefinition时会触发Bean的预实例化,这个过程会触发bean的依赖注入,否则就在用户第一次调用getBean向IOC容器索要bean时触发。下面来看一看这个过程是如何实现的,首先来看看AbstractApplicationContext中的refresh方法

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			prepareRefresh();

			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			prepareBeanFactory(beanFactory);

			try {
				
				postProcessBeanFactory(beanFactory);

				invokeBeanFactoryPostProcessors(beanFactory);

				registerBeanPostProcessors(beanFactory);

				initMessageSource();

				initApplicationEventMulticaster();

				onRefresh();

				registerListeners();
                                //这里是对lazy-init属性进行处理的地方
				finishBeanFactoryInitialization(beanFactory);

				finishRefresh();
			}

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

				
				destroyBeans();

				cancelRefresh(ex);

				throw ex;
			}

			finally {
		
				resetCommonCaches();
			}
		}
	}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		
		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));
		}

		
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
				@Override
				public String resolveStringValue(String strVal) {
					return getEnvironment().resolvePlaceholders(strVal);
				}
			});
		}

		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		beanFactory.setTempClassLoader(null);

		beanFactory.freezeConfiguration();
                //这个方法中有对lazy-init属性的相关处理,方法的具体实现在DefaultListableBeanFactory中
		beanFactory.preInstantiateSingletons();
	}
public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Pre-instantiating singletons in " + this);
		}

		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
                //遍历所有的beanName
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                        //注入所有的单例的并且未配置lazy-init属性或lazy-init属性为false的bean
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean 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());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					getBean(beanName);
				}
			}
		}
                
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedAction<Object>() {
						@Override
						public Object run() {
							smartSingleton.afterSingletonsInstantiated();
							return null;
						}
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

三、FactoryBean的实现

FactoryBean是一种特殊的Bean,它是一个可以产生或者修饰对象的工厂Bean,与设计模式中的工厂模式以及装饰器模式类似。通过实现org.springframework.beans.factory.FactoryBean来创建一个FactoryBean,我们调用它的getBean方法时,得到的是它的生成的对象,如果想得到Factory本身,需要在前面加上转义符“&”。上一篇我们在分析通过getBean方法触发的依赖注入过程时提到过,AbstractBeanFactory中的getObjectForBeanInstance方法中进行了对FactoryBean的相关处理,代码如下

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

		//如果bean不是FactoryBean的实例并且以"&"开头就抛出异常
		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}

		//如果bean不是FactoryBean的实例或者是FactoryBean的实例并且以"&"开头就直接返回
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

		Object object = null;
		if (mbd == null) {
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			//这里从FactoryBean中取得Bean
                        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		    //如果BeanFactory为单例的并且已经被实例化过
                    if (factory.isSingleton() && containsSingleton(beanName)) {
			synchronized (getSingletonMutex()) {
                                //从缓存中获取
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
                                        //创建bean的具体实现
					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)
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
						object = alreadyThere;
					}
					else {
						if (object != null && shouldPostProcess) {
                                                        //BeanPostProcessor中的方法只会处理FactoryBean而不会处理FactoryBean生成的对象,如果需要对生成的对象进行处理,可以自己覆盖这个方法
							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 = 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;
		}
	}
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {

		Object object;
		try {
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
                                                                //在这里调用FactoryBean的getObject方法来生成需要的对象
								return factory.getObject();
							}
						}, acc);
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
                                //在这里调用FactoryBean的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");
		}
		return object;
	}

四、Spring自动装配(Autowire)的实现

我们前面分析的依赖关系一直是显式的配置在配置文件中来对bean的依赖关系进行管理的,Spring中还可以通过配置autowire属性来隐式的进行依赖关系的配置,IOC容器会根据autowire配置的属性来自动查找属性的名字或者类型来自动的完成依赖注入。利用这一特性可以简化配置文件中的配置,但是它也有一定的局限性,例如它不能自动装配基本类型、字符串、数组等,而且它进行的依赖注入是容器自己判断的,如果配置不当反而会有不好的效果,所以要谨慎使用。下面我们来看看这一特性是如何实现的。对于byName和byType两种配置方式的实现在AbstractAutowireCapableBeanFactory的populateBean方法中,这个方法在上一篇分析bean的依赖注入时有详细的说明

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    //省略部分代码    
    ···
                //对autowire的byName和byType的处理
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			//对于byName的处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// 对byType的处理
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			pvs = newPvs;
		}

    //省略部分代码    
    ···
}
protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
                //需要注入的属性名称
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			    //如果容器中包含指定名称的bean
                            if (containsBean(propertyName)) {
				//触发属性的依赖注入
                                Object bean = getBean(propertyName);
				//将需要注入的属性添加到PropertyValues中
                                pvs.add(propertyName, bean);
                                //注册bean的依赖关系
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}
protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
                //获取需要注入的属性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			try {
                                //获取注入的属性对应的PropertyDescriptor对象
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				if (Object.class != pd.getPropertyType()) {
                                        //获取set方法
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					
					boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());                                    
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                                        //获取需要注入的属性对象
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
					if (autowiredArgument != null) {
                                                //将需要注入的属性添加到bean的PropertyValues中
						pvs.add(propertyName, autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isDebugEnabled()) {
							logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}

对于autowire配置为constructor的相关处理在AbstractAutowireCapableBeanFactory的createBeanInstance方法中,这个方法用来生产具体的bean的对象,这个方法也在上一篇中有详细的说明,我们在这里只简单看看对这个配置的处理

    //如果autowire配置为constructor,那么会调用对应的构造器来生成对象
    if (ctors != null ||
		mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
		mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
    }

对于SpringIOC的分析就到此结束了,下一篇开始分析Spring的AOP的实现。

猜你喜欢

转载自blog.csdn.net/qq423196778/article/details/81123978