Spring容器Bean的创建流程
文章目录
- 前言
- 1. Bean创建流程概览
- 2. 源码分析
- 2.1 getBean()
- 2.2 doGetBean()
- 2.3 getSingleton()
- 2.4 createBean()
- 2.5 doCreateBean()
- 3. 时序图概括
- 总结
前言
本文将从源码角度分析Spring容器中Bean的创建流程,重点关注从getBean()
方法开始的完整调用链路,通过源码分析Spring IoC容器的核心工作机制。
1. Bean创建流程概览
从getBean()方法开始,Spring Bean的创建流程如下:
getBean() → doGetBean() → getSingleton() → createBean() → doCreateBean()
2. 源码分析
2.1 getBean()
@Override
public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);
}@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);
}
这是Bean获取的统一入口,所有的getBean重载方法最终都会调用doGetBean()
方法。
2.2 doGetBean()
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) {// 如果是FactoryBean,调用getObject()方法bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// 第3步:检查原型Bean是否存在循环依赖if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// 第4步:检查父容器BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {return parentBeanFactory.getBean(originalBeanName(name), requiredType);}// 第5步:标记Bean为已创建状态if (!typeCheckOnly) {markBeanAsCreated(beanName);}try {// 第6步:获取Bean定义,合并父Bean定义final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// 第7步:处理depends-on依赖String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {registerDependentBean(dep, beanName);getBean(dep); // 递归创建依赖的Bean}}// 第8步:创建Bean实例if (mbd.isSingleton()) {// 单例模式sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try {return createBean(beanName, mbd, args);} catch (BeansException ex) {destroySingleton(beanName);throw ex;}}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// 原型模式Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {// 其他作用域(request、session等)String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}returnthis.adaptBeanInstance(name, beanInstance, requiredType);;
}
2.3 getSingleton()
// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {// 先从一级缓存获取Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// 检查是否正在销毁if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName, "...");}// 创建前的准备工作beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<Exception>();}try {// 调用ObjectFactory创建BeansingletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}// 创建后的清理工作afterSingletonCreation(beanName);}if (newSingleton) {// 将新创建的单例添加到缓存中addSingleton(beanName, singletonObject);}}return singletonObject;}
}
2.4 createBean()
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {RootBeanDefinition mbdToUse = mbd;// 第1步:解析Bean的Class类型Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// 第2步:准备方法覆盖try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// 第3步:给BeanPostProcessor一个机会返回代理对象Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean; // 如果返回了代理对象,直接返回}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}// 第4步:执行实际的Bean创建Object beanInstance = doCreateBean(beanName, mbdToUse, args);return beanInstance;
}
2.5 doCreateBean()
// AbstractAutowireCapableBeanFactory.java - 最核心的Bean创建方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,final Object[] args) throws BeanCreationException {// Bean包装器BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 第1步:实例化BeaninstanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);mbd.resolvedTargetType = beanType;// 第2步:允许post-processor修改MergedBeanDefinitionsynchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// 第3步:解决循环依赖boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {addSingletonFactory(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {return getEarlyBeanReference(beanName, mbd, bean);}});}// 第4步:初始化Bean实例Object exposedObject = bean;try {// 属性填充populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {// 初始化BeanexposedObject = 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);}}// 第5步:处理循环依赖的检查if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {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);}}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.");}}}}// 第6步:注册DisposableBeantry {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;
}
3. 时序图概括
总结
在学习SpringIoC容器中Bean是如何创建的过程中,我翻阅的无数次源码,也借鉴了很多大佬的文章,一次一次的打断点需要很大的耐心,虽然现在的学习没有得到正反馈,但是在将来的一天当你把源码烂熟于心是,不管是写博客总结还是在面试中被问到,可以胸有成竹的回答出来。希望大家可以更好的理解Bean的创建流程。