spring源码:IOC容器存储和Bean对象的完整加载流程

IOC容器的对象存储

1、单例Bean对象

spring主要通过BeanFactory接口的getBean方法来从IOC容器,即BeanFactory的实现类中获取某个bean对象实例,但是BeanFactory并不直接操作bean对象的存取,而是通过BeanRegistry的接口来处理,类似读写分离的概念。其中,单例bean的注册和获取通过实现SingletonBeanRegistry接口,分别对应registerSingleton和getSingleton方法,其实现类为DefaultSingletonBeanRegistry,已注册的单例bean就保存在该实现类的singletonObjects缓存map中,此外还包括用于处理循环依赖的三级缓存等。单例bean对象的存取实际就是在这些map中进行

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

	/** 单例bean缓存: bean name to bean instance. */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	/** 三级缓存:单例对象工厂: bean name to ObjectFactory. */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	/** 二级缓存:早期单例bean对象缓存: bean name to bean instance. */
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

	/** 已注册的单例bean名称 */
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

	/** 当前正在创建的bean名称,防止重复创建,比如处理循环依赖时使用. */
	private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

   //注册单例bean对象
    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		Assert.notNull(beanName, "Bean name must not be null");
		Assert.notNull(singletonObject, "Singleton object must not be null");
		synchronized (this.singletonObjects) {
			Object oldObject = this.singletonObjects.get(beanName);
			if (oldObject != null) {
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			addSingleton(beanName, singletonObject);
		}
	}

	//添加单例bean对象到ioc容器
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}
}
//获取单例bean
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

2、工厂Bean(FactoryBean)对象

FactoryBean创建的bean对象容器FactoryBeanRegistrySupport:继承于DefaultSingletonBeanRegistry,factoryBeanObjectCache 中的bean对象实例是通过调用FactoryBean的getObject方法获取的bean对象。

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {

	/** Cache of singleton objects created by FactoryBeans: FactoryBean name to object. */
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);

}

3、完整的IOC容器

BeanFactory的基础抽象实现类AbstractBeanFactory继承了BeanFactory接口和SingletonBeanRegistry接口,具备完整的IOC功能入口
在这里插入图片描述

Bean对象的完整加载流程

spring主要通过ApplicationContext来对外提供IOC服务,即与应用代码集成,而不是在应用代码中直接使用BeanFactory。通过ApplicationContext来初始化BeanFactory和从BeanFactory获取应用所需的bean对象。其中applicationContext的完整生命周期主要定义在AbstractApplicationContext的refresh方法中
在这里插入图片描述

applicationContext生命周期

  • prepareRefresh
    主要做一些准备工作,比如initPropertySources 初始化上下文环境中的占位符属性源

  • obtainFreshBeanFactory
    获取一个全新的BeanFacory, 如果context是AbstractRefreshableApplicationContext的子类,比如XmlApplicationContext,则创建完beanFacory后直接调用loadBeanDefinitions来从配置文件中加载所有bean

  • prepareBeanFactory(beanFactory);
    为beanFactory添加基础配置,比如设置BeanClassLoader、添加BeanPostProcessor(ApplicationContextAwareProcessor、ApplicationListenerDetector)、添加自动装配忽略的接口依赖(EnvironmentAware、ApplicationContextAware等)、注册可解析的依赖(BeanFactory、ApplicationContext等)、注册默认的环境相关bean(environment、systemProperties、systemEnvironment)

  • postProcessBeanFactory(beanFactory);
    在加载完bean但还没有实例化之前操作,比如增加beanPostProcessor等。
    在web相关的子类实现中处理:如注册ServletContextAwareProcessor;注册scope(request、session、globalSession、application);
    注册环境bean实例(servletContext、servletConfig、contextParameters、contextAttributes

  • invokeBeanFactoryPostProcessors(beanFactory);
    调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法,实例化并调用所有已注册的BeanFactoryPostProcessor,主要是对ConfigurationClassPostProcessor的调用处理
    在这里插入图片描述

注册BeanDefinitionRegistryPostProcessor实例并调用:注册ConfigurationClassPostProcessor遍历所有BeanDefinition,使用ConfigurationClassParser处理所有candidates:
	处理@PropertySources、@ComponentScan,使用ComponentScanAnnotationParser处理;处理@ImportResource;处理@Bean methods,之后使用ConfigurationClassBeanDefinitionReader.loadBeanDefinitions注册bean和类中的@Bean 及autowire、initMethod、destroyMethod
	registerBeanDefinitionForImportedConfigurationClass
	loadBeanDefinitionsForBeanMethod
	loadBeanDefinitionsFromImportedResources
	loadBeanDefinitionsFromRegistrars
  • registerBeanPostProcessors(beanFactory);
    调用PostProcessorRegistrationDelegate.registerBeanPostProcessors方法,实例化并注册所有BeanPostProcessor,在bean实例化之前调用在这里插入图片描述
添加BeanPostProcessorChecker;获取所有BPP, 将实现 PriorityOrdered、Ordered 和其余的BPP分开注册所有PriorityOrdered BPP:比如:CommonAnnotationBeanPostProcessors,AutowireAnnotaionBeanPostProcessors,RequirdAnnotaionBeanPostProcessors;
	注册册所有Ordered BeanPostProcessors:比如:AnnotationAwareAspectJAutoProxyCreator
	注册所有普通BeanPostProcessors:注册ApplicationListenerDetector
  • initMessageSource();
    用于国际化i18n

  • initApplicationEventMulticaster();
    注册事件多播器

  • onRefresh();
    模板方法供子类实现,用于在bean实例化之前进行特殊处理,如注册themeSource

  • registerListeners();
    注册所有实现了ApplicationListener的监听器,注册到applicationEventMulticaster

  • finishBeanFactoryInitialization(beanFactory);
    bean实例化,完成bean从beanDefinition到bean实例的整个过程,也就是我们关心的bean对象的完整加载过程就在这里进行,主要入口在DefaultListableBeanFactory的preInstantiateSingletons方法中

  • finishRefresh();
    完成此上下文的刷新,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent

以上是ApplicationContext的整个初始化过程,而我们关心的bean对象由BeanDefinition转化为Bean实例对象的完整流程入口主要在finishBeanFactoryInitialization方法中,即DefaultListableBeanFactory的preInstantiateSingletons方法。

public void preInstantiateSingletons() throws BeansException {
		
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//返回一个合并的 RootBeanDefinition,合并父Bean特性
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//如果非抽象类且单例且非懒加载则执行Bean实例化
				if (isFactoryBean(beanName)) { //判断是是否是工厂Bean
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else { //如果不是工厂bean则直接调用getBean
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

下面详细分析下整个过程

单例bean加载流程

1、依次进入AbstractBeanFactory的getBean、doGetBean方法。先调用getSingleton检查三级缓存,如果存在bean实例则返回,否则的话校验prototypesCurrentlyInCreation中是否存在该beanName,prototypesCurrentlyInCreation是定义的一个本地线程变量,用来保存当前正在创建的bean名称,如果该本地线程变量中存在该beanName,则抛出一个疑似循环依赖的异常;
2、获取parentBeanFactory并检查当前beanFactory是否存在该beanDefinition,如果不存在并且parentBeanFactory不为空的话则调用parentBeanFactory的getBean方法,交给parentBeanFactory来创建bean对象;
3、遍历依赖bean(通过@DependsOn注解或depends-on配置的依赖组件),并对每个依赖bean调用getBean方法,确保每个依赖的bean先被实例化;
4、如果是单例bean则调用getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法获取单例bean对象,其中singletonFactory的getObject方法主要是调用createBean方法,进入真正的创建bean实例的过程;
在这里插入图片描述

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
		  //先从一级单例缓存中获取bean实例对象
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
		        //校验是否在销毁状态中
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				//校验inCreationCheckExclusions中如果不存在并且singletonsCurrentlyInCreation已经存在的话则抛出循环依赖异常 
				beforeSingletonCreation(beanName); 
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
				    //调用createbean方法创建bean实例对象
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					//从singletonsCurrentlyInCreation中移除,校验inCreationCheckExclusions和singletonsCurrentlyInCreation 中如果都不存在则抛异常 
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
				    //添加到一级缓存中,同时从二三级缓存中移除
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

5、进入creatBean方法,该方法定义在AbstractAutowireCapableBeanFactory抽象类中。首先调用resolveBeanClass,确保bean对应的class类已经被解析,之后调用resolveBeforeInstantiation方法,使用InstantiationAwareBeanPostProcessor的实现类AbstractAutoProxyCreator的applyBeanPostProcessorsBeforeInstantiation来处理bean的代理类,用于返回一个代理对象,实现AOP。如果applyBeanPostProcessorsBeforeInstantiation返回的bean不为空,则调用applyBeanPostProcessorsAfterInitialization方法,即遍历所有BeanPostProcessors并调用postProcessAfterInitialization方法,最后直接返回该代理对象。
在这里插入图片描述

6、如果上述代理类为空则进入doCreateBean方法,进入创建bean实例对象的核心流程。

  • 6.1 调用createBeanInstance方法,使用构造函数创建bean实例
    在determineConstructorsFromBeanPostProcessors方法中调用AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors方法,基于贪婪原则选择能注入最多bean对象的构造函数,如果只存在一个显式定义的构造函数,则使用这个构造函数;否则先基于构造函数的参数个数对所有构造函数进行降序排序,然后遍历检查这些构造函数。选中最合适的构造函数后,则进行构造函数的属性对象的注入。
    主要是在createArgumentArray方法处理构造函数的属性注入问题,最终会调用到BeanFactory的getBean方法从BeanFactory获取所依赖的其他对象。如果BeanFactory当前还不存在该依赖的bean对象,则会在getBean方法中创建该bean对象并返回。所以如果该被依赖的bean对象如果也在构造函数中依赖了当前正在创建的bean对象,则该依赖的bean对象就无法创建了,故出现了循环依赖问题,导致程序异常退出。

  • 6.2 调用applyMergedBeanDefinitionPostProcessors
    调用MergedBeanDefinitionPostProcessor实现类的postProcessMergedBeanDefinition方法,主要处理有以下两种:
    1、AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition处理注入的字段、方法(@Autowired、@Value等)
    2、CommonAnnotationBeanPostProcessor 处理@PostConstruct、@PreDestroy等

  • 6.3 添加到三级缓存用于解决循环依赖问题
    如果是单例并且allowCircularReferences为ture即允许循环依赖并且singletonsCurrentlyInCreation中存在该beanName的话则添加到三级缓存singletonFactories中,用于处理循环依赖问题。其中singletonFactory主要是通过SmartInstantiationAwareBeanPostProcessor的实现类AbstractAutoProxyCreator的getEarlyBeanReference方法
    在这里插入图片描述

  • 6.4 调用populateBean方法填充Bean属性
    1、先调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation,在设置属性之前修改 bean。例如,这可以用于支持字段注入的样式。
    2、autowireByName或者autowireByType,通过名称或者类型进行依赖注入,如果是这种方式出现的循环依赖则spring能完美解决
    3、调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法进行属性值注入和setter方法注入
    4、applyPropertyValues

  • 6.5 调用initializeBean方法初始化bean,应用接口回调方法和init方法
    1、调用invokeAwareMethods,如果类实现了BeanNameAware、BeanClassLoaderAware和BeanFactoryAware则调用对应的set方法进行属性注入
    在这里插入图片描述
    2、调用applyBeanPostProcessorsBeforeInitialization方法,即调用所有BeanPostProcessor的postProcessBeforeInitialization方法
    3、调用invokeInitMethods方法,如果实现了InitializingBean则调用afterPropertiesSet方法,然后调用自定义init方法(在bean标签的init-method中指定的处理方法或者使用@Bean注解的initMethod的指定方法)
    4、调用applyBeanPostProcessorsAfterInitialization方法,即调用所有BeanPostProcessor的postProcessAfterInitialization方法

  • 6.6 调用registerDisposableBeanIfNecessary,将beanName添加到disposableBeans缓存中
    disposableBeans的key为beanName,value为new一个DisposableBean的实现类DisposableBeanAdapter的对象。在spring容器关闭时,从AbstractApplicationContext的doClose开始,调用BeanFactory的destroySingletons,最终销毁每个singleton的时候,从以上disposableBeans获取该bean对应的DisposableBeanAdapter,然后调用DisposableBeanAdapter的destroy。
    DisposableBeanAdapter的destroy方法实现如下:先调用DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法,再调用DisposableBean,最后调用destroy-method。

public void destroy() {
		if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
			for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
				processor.postProcessBeforeDestruction(this.bean, this.beanName);
			}
		}

		if (this.invokeDisposableBean) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
			}
			try {
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((DisposableBean) this.bean).destroy();
						return null;
					}, this.acc);
				}
				else {
					((DisposableBean) this.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);
				}
			}
		}

		if (this.destroyMethod != null) {
			invokeCustomDestroyMethod(this.destroyMethod);
		}
		else if (this.destroyMethodName != null) {
			Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
			if (methodToInvoke != null) {
				invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
			}
		}
	}

以上,即spring bean的完整加载流程。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值