spring源码学习(二)
本篇文章,来介绍finishBeanFactoryInitialization(beanFactory);这个方法主要是完成bean的实例化,
invokeBeanFactoryPostProcessors(beanFactory);负责把所有的bean扫描到beanDefinitionMap中;
下面来说是如何初 1062 始化的
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
我们直接从这个方法开始说起,前面的调用链简单,就不说了
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { /** * 通过name获取beanName,这里不使用name直接作为beanName有两个原因: * 1.name可能是以&开头的,表明调用者想获取FactoryBean本身,而非FactoryBean;在beanFactory中factoryBean的存储也是map格式 * <beanName,bean> 只是说,普通的beanName是没有&这个字符串的,所以,需要将name的首字母移除,这样才能从缓存中拿到factoryBean * 2.还是别名的问题,需要转换 */ final String beanName = transformedBeanName(name); Object bean; /** * 1.从单例池中获取当前bean * 2.这里是循环依赖的重要方法之一 * */ // Eagerly check singleton cache for manually registered singletons. 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 + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. /** * 这里判断bean是否在创建过程中,是第二次调用的时候 才会判断;如果是第一次执行到这里,set集合是空(这里判断的是原型bean) */ if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //添加到alreadyCreated集合当中,表示当前bean已经创建过一次了 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance.如果当前bean是单实例的,就调用createBean if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { 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); } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } return (T) bean; }
粘贴出来的方法删减了一部分代码,我们只说单实例bean的初始化;
在判断当前bean是单实例的时候,会调用createBean;在getSingleton这里,有一行代码,是把当前bean添加到一个set集合中(这个set集合表示当前bean正在创建过程中),
这个set是用来解决循环依赖问题的,在后面,会单独抽出一篇来介绍循环引用是如何解决的,在这里就先跳过;
576
在createBean的方法中,会调用createBeanInstance(beanName, mbd, args); 这个方法主要是完成bean的初始化,在方法中会调用org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors;
这个后置处理器的determineCandidateConstructors方法来推断使用哪个构造函数来初始化;
这个方法里面,我目前也正在学习,后续会贴出对这个方法的学习笔记,这里先暂时跳过;(我们就认为createBeanInstance方法完成了bean的创建),
推断出使用哪个构造函数之后,会初始化bean,返回的是一个BeanWrapper对象。这里创建出来的仅仅是bean对象;需要经过后面的属性注入,以及初始化,才会变成我们所说的spring bean对象;
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { 3 // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { /** * 创建bean实例,并将bean实例包裹在BeanWrapper实现类对象中返回, * createBeanInstance中包含三种创建bean的方式 * 1.通过工厂方法创建bean实例 * 2.通过构造方法自动注入的方式创建bean实例 * 3.通过无参构造方法创建bean实例 * * 如果bean的配置中配置了lookup-method和replace-method 则会使用增强bean实例 * * 在这个方法中完成了对bean的创建(仅仅是new出来,也就是说在这个方法里面推断要使用哪个构造函数来创建bean对象) * 然后完成bean的初始化 * */ instanceWrapper = createBeanInstance(beanName, mbd, args); 24 } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { //mpy 第三次调用后置处理器 缓存注解信息 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. 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") 2393 ; } //mpy 第四次调用后置处理器 获取一个提前暴露的对象 用来解决循环依赖 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { //在populateBean(beanName, mbd, instanceWrapper);方法中完成第五次第六次调用后置处理器 populateBean(beanName, mbd, instanceWrapper); //在initialzeBean中完成第七次第八次后置处理器调用 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); } } return exposedObject; }
上面这个方法中,调用第四次后置处理器这里,返回了一个object对象,这个方法是为了完成循环依赖的,放到后面一起讲,
在populateBean中,会完成属性的注入,比如@AutoWired,@Value这个属性值注入
initializeBean方法,主要是调用bean的初始化方法
bean的初始化有三种方式:
1.@Bean注解中指定 initMethod destroyMethod
2.@PostConstruct @PreDestroy
3.实现DisposableBean和InitializingBean接口
在方法执行完之后,会把创建好的bean对象存放到singletonObjects这个map中,这个map存放的是所有实例化好的对象;如果bean是原型的,在第二次getBean的时候,会从这个map中获取到bean对象
从狭义上来讲,singletonObjects就是我们所说的spring容器
- spring容器初始化,bean加载生成过程,源码解析学习
- Spring源码学习-PropertyPlaceholderHelper
- spring源码学习之路---IOC初探(二)
- Spring源码学习
- Spring Aop源码学习--JoinPoint连接点
- 【Spring-web】RestTemplate源码学习——梳理内部实现过程
- mybatis源码学习--spring+mybatis注解方式为什么mybatis的dao接口不需要实现类
- spring源码学习笔记-初始化(四)-PostProcessor
- Spring源码学习:DefaultAopProxyFactory
- # spring 源码学习笔记 未编辑完成
- Spring源码学习(一)------ IoC .
- spring view 源码学习
- Spring源码学习20160120
- spring源码学习(七)Bean的加载(下)
- Spring源码学习--自定义标签
- Spring源码学习(一)—工具准备和环境搭建
- Spring源码学习之容器的功能扩展
- Spring源码阅读学习一
- Spring源码学习之:@async 方法上添加该注解实现异步调用的原理
- Spring源码学习(二)------ AOP