前言:
createBean是创建Bean的主要方法
该方法位于:AbstractBeanFactory的doGetBean方法中的createBean调用、
createBean方法流程图:
createBean源码解析:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;//该参数是从AbstractBeanFactory的doGetBean传递过来的父子容器合并BeanDefinition
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
//克隆一份BeanDefinition,用来设置上加载出来的class对象
//之所以后续用该副本操作,是因为不希望将解析的class绑定到缓存里的BeanDefinition
//因为class有可能是每次都需要动态解析出来的
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
//校验和准备Bean中的方法覆盖
try {
mbdToUse.prepareMethodOverrides();//如果是0个则抛异常,如果是1个也就没有重载的必要
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
//resolveBeforeInstantiation只是针对有自定义的targetsource,
//因为自定义的targetsource不是spring的bena,那么肯定不需要进行后续的一系列的实例化,初始化。
//所以可以在resolveBeforeInstantiation直接进行proxy
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
//如果这里有处理器在bean创建的之前 给出了代理bean,则无需执行后续的逻辑,
// 直接返回用户给出的bean
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//创建Bean的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
createBean方法大致流程:
(1)判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载(如果可以,克隆一份BeanDefinition)
(2)用BeanDefinition副本调用prepareMethodOverrides()方法,进行校验Bean和准备Bean中的方法覆盖(处理方法覆盖)
(3)⭐处理Bean配置的初始化前后的处理器(前置:该方法里头会调用所有的Bean处理器,如果处理器中有调换了bean的,则返回bean,如果没有则返回null)
(4)⭐调用doCreateBean()方法,该方法是创建Bean的入口
doCreateBean方法流程图:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
//bean实例包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//从未完成创建的包装Bean缓存中清理并获取相关中的包装Bean实例,毕竟是单例,只能存一份
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean的时候,这里创建bean的实例有三种方法
//1.工厂方法创建
//2.构造方法的方式注入
//3.无参构造方法注入
instanceWrapper = createBeanInstance(beanName, mbd, args);//********
}
//获取被包装的Bean,后续对bean的改动相对于对Wrapper的改动,反之依然
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.
//调用BeanDefinition属性合并完成后的BeanPostProcessor后置处理器
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//@Autowired、@Value标记的属性在这里获取
//应用合并后的BeanDefinition后置处理器
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.
//向容器中缓存单例模式的Bean对象,以防循环引用
//判断是否是早期引用的bean,如果是,则允许其提前暴露引用
// 这里判断的逻辑主要有三个∶
//1.是否为单例
//2 是否允许循环引用
//3.是否是在创建中的bean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
//将还没完全配置好的bean存入到三级缓存中供其他bean使用(暴露引用)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
//这里的getEarlyBeanReference()方法,并不是在此调用,而是声明好了方法
//具体的调用在Spring的AbstractBeanFactory的doGetBean的第三行调用
// DefaultSingletonBeanRegistry类的getSingleton方法中,调用
// singletonFactory.getObject()(单例工厂的getObject方法返回实例对象)
}
// Initialize the bean instance.
//Bean对象的初始化,依赖注入在此触发
//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;//暴露的对象
try {
//填充bean实例的属性
populateBean(beanName, mbd, instanceWrapper);
//初始化bean,过程如下:
//1.判断是否实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware方法,
//如果有,则设置相关的属性
//2.调用bean初始化前的前置(BeanPostProcessor)操作
//3.执行初始化的方法
//如果有InitializingBean,则调用afterPropertiesSet
//如果有InitMethod,则调用初始方法
//4.调用bean初始化的后置(BeanPostProcessor)操作
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);
}
}
//若允许循环依赖,则解决相关的循环依赖
//earlySingletonExposure是前面代码判断出来的是否:暴露引用bean
if (earlySingletonExposure) {
//获取指定名称的已注册的单例模式Bean对象
//这里的getSingleton()从三层缓存中依次去获取,由于
//先前我们已经将对象存入到三级缓存中,所有这里在三级缓存获取得到
//然后缓存中的对象被放到了二级缓存中,三级中移除了
Object earlySingletonReference = getSingleton(beanName, false);//
if (earlySingletonReference != null) {
//如果经过initializeBean执行后返回的bean还是同一个(不是代理对象实例,即没有被增强)
if (exposedObject == bean) {
//确保根据名称获取到的
exposedObject = earlySingletonReference;
}
//如果上面的if没通过,则表明引用的bean和注入的bean不一致,则需要看看依赖于此Bean的先前是否已经
//allowRawInjectionDespiteWrapping标注是否允许此Bean的原始类型被注入到其他Bean里面,
//即使自己最终会被包装(代理)
//dependentBeanMap记录着每个依赖于此Bean的Bean实例集合
//当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(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.");
}
}
}
}
doCreateBean方法大致流程:
(1)判断BeanDefinition是不是单例的,如果是单例的,从未完成创建的包装Bean缓存中清理并获取相关中的包装Bean实例,毕竟是单例,只能存一份
(2)判断第一步中获到的包装Bean实例如果是空的,调用createBeanInstance()方法创建bean,这里创建bean的实例有三种方法
(1)尝试获取BeanDefinition里面的Class对象
(2)检查是否有权通过反射创建private的Class
(3)如果bean使用的是java自带的函数式接口Supplier(工厂方法),则调用里头的get创建返回bean实例
(4)如果BeanDefinition里面有定义Spring的工厂方法如(factory-method),则调用factory-method创建返回实例
(5)查询BeanDefinition中有没有缓存好的构造函数或者工厂方法,有则调用创建返回实例
(6)判断是否使用(带惨构造函数装配)如果都不是最终调用无参构造函数创建返回实例
(3)获取被包装的Bean,后续对bean的改动相对于对Wrapper的改动,反之依然,获取实例化对象的类型并放入BeanDefinition中
(4)对BeanDefinition的后置处理器上锁操作,判断BeanDefinition没有使用后置处理器,后调用applyMergedBeanDefinitionPostProcessors()方法应用合并后的BeanDefinition后置处
理器(@Autowired、@Value标记的属性在这里获取) applyMergedBeanDefinitionPostProcessors内部跟绝大部分后置处理器一样采用了责任链模式,循环遍历所有后置处理器,
IF实现了MergedBeanDefinitionPostProcessor接口的 后置处理器便调用postProcessMergedBeanDefinition方法这里我们重点关注:AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()
(1)进入AutowiredAnnotationBeanPostProcessor类,首先我们可以看到该类的无参构造方法中对@Autowired、@Value注解添加到了该类的成员变量里。
(2)我们查看postProcessMergedBeanDefinition()方法
(A)首先第一行调用了findAutowiringMetadata()方法(寻找被注解标记的元数据)
(1)用类名作为cacheKey(缓存建名)
(2)使用cacheKey在缓存容器中查找是否有相关缓存
(3)如果缓存容器中没有metadata(元数据)|| metadata的class和给定的clazz不符合则重新获取到构建好的metadata实例并放入到缓存容器中(双重锁机制)
(B)用前面查找到的metadata调用checkConfigMembers方法,需要Spring用默认策略放到的InjectedElements(注入元素表)
(5)判断是否是早期引用的bean,如果是,则允许其提前暴露引用(单例、允许循环引用、创建中的bean)