【spring 4.3.7】Spring IoC源码学习:BeanFactory.getBean() 详解

前言

《Spring IoC源码学习:finishBeanFactoryInitialization() 详解》

整体流程如下:
在这里插入图片描述

1. getBean()

AbstractBeanFactory是BeanFactory的子类,负责bean的具体实现。

@Override
public Object getBean(String name) throws BeansException {
    
    
    // 获取name对应的bean实例,如果不存在,则创建一个
    return doGetBean(name, null, null, false);
}

见 doGetBean() 方法详解。

2. doGetBean()

protected <T> T doGetBean(
        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
        throws BeansException {
    
    
    // 1.解析beanName,主要是解析别名、去掉FactoryBean的前缀“&”
    final String beanName = transformedBeanName(name);
    Object bean;
 
    
    // 2.尝试从单例缓存()中获取beanName对应的实例
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
    
    
        // 3.如果beanName的实例存在于缓存中
        
        // 3.1 返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
    
    
        
        
        // 4.scope为prototype的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常。
        // 例子:如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖
        if (isPrototypeCurrentlyInCreation(beanName)) {
    
    
            throw new BeanCurrentlyInCreationException(beanName);
        }
 
        // Check if bean definition exists in this factory.
        // 5.获取parentBeanFactory
        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 5.1 如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    
    
            // Not found -> check parent.
            // 5.2 将别名解析成真正的beanName
            String nameToLookup = originalBeanName(name);
            // 5.3 尝试在parentBeanFactory中获取bean对象实例
            if (args != null) {
    
    
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            } else {
    
    
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }
 
        if (!typeCheckOnly) {
    
    
            // 6.如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
            markBeanAsCreated(beanName);
        }
 
        try {
    
    
            // 7.根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 7.1 检查MergedBeanDefinition
            checkMergedBeanDefinition(mbd, beanName, args);
 
            // Guarantee initialization of beans that the current bean depends on.
            // 8.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
    
    
                // 8.1 遍历当前bean依赖的bean名称集合
                for (String dep : dependsOn) {
    
    
                    // 8.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
                    if (isDependent(beanName, dep)) {
    
    
                        // 8.3 如果是循环依赖则抛异常
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 8.4 将dep和beanName的依赖关系注册到缓存中
                    registerDependentBean(dep, beanName);
                    // 8.5 获取dep对应的bean实例,如果dep还没有创建bean实例,则创建dep的bean实例
                    getBean(dep);
                }
            }
 
            // Create bean instance.
            // 9.针对不同的scope进行bean的创建
            if (mbd.isSingleton()) {
    
    
                // 9.1 scope为singleton的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
    
    
                    @Override
                    public Object getObject() throws BeansException {
    
        //
                        try {
    
    
                            // 9.1.1 创建Bean实例
                            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;
                        }
                    }
                });
                // 9.1.2 返回beanName对应的实例对象
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else if (mbd.isPrototype()) {
    
    
                // 9.2 scope为prototype的bean创建
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
    
    
                    // 9.2.1 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
                    beforePrototypeCreation(beanName);
                    // 9.2.2 创建Bean实例
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
    
    
                    // 9.2.3 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
                    afterPrototypeCreation(beanName);
                }
                // 9.2.4 返回beanName对应的实例对象
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
    
    
                // 9.3 其他scope的bean创建,可能是request之类的
                // 9.3.1 根据scopeName,从缓存拿到scope实例
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
    
    
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
    
    
                    // 9.3.2 其他scope的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
    
    
                        @Override
                        public Object getObject() throws BeansException {
    
    
                            // 9.3.3 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
                            beforePrototypeCreation(beanName);
                            try {
    
    
                                // 9.3.4 创建bean实例
                                return createBean(beanName, mbd, args);
                            } finally {
    
    
                                // 9.3.5 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    // 9.3.6 返回beanName对应的实例对象
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
    
    
                    throw new BeanCreationException(beanName,
                            "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        } catch (BeansException ex) {
    
    
            // 如果创建bean实例过程中出现异常,则将beanName从alreadyCreated缓存中移除
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }
 
    // Check if required type matches the type of the actual bean instance.
    // 10.检查所需类型是否与实际的bean对象的类型匹配
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
    
    
        try {
    
    
            // 10.1 类型不对,则尝试转换bean类型
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        } catch (TypeMismatchException ex) {
    
    
            if (logger.isDebugEnabled()) {
    
    
                logger.debug("Failed to convert bean '" + name + "' to required type '" +
                        ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    // 11.返回创建出来的bean实例对象
    return (T) bean;
}

2.尝试从缓存中获取beanName对应的实例:

  • 在缓存从的话,则从缓存从读取实例,对应步骤3
  • 否则新建实例,对应步骤4-9

3.从缓存中取

  • 3.1 对FactoryBean特殊处理

4.检查循环依赖
5.考虑parentBeanFactory创建bean:
    如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例

8.递归创建依赖的bean
9.创建实例,调用createBean()

  • 9.1单例
    • 9.1.1 创建Bean实例,调用createBean()
  • 9.2 多例
    • 9.2.2 创建Bean实例,调用createBean()

2.1 AbstractAutowireCapableBeanFactory.createBean()

进一步调用doCreateBean()

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    
    
   
    RootBeanDefinition mbdToUse = mbd; 
    
    // 1.解析beanName对应的Bean的class类型,后期反射创建对象
    //例如:com.joonwhee.open.demo.service.impl.UserServiceImpl
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    
    
        // 如果resolvedClass存在,并且mdb的beanClass类型不是Class,并且mdb的beanClass不为空(则代表beanClass存的是Class的name),
        // 则使用mdb深拷贝一个新的RootBeanDefinition副本,并且将解析的Class赋值给拷贝的RootBeanDefinition副本的beanClass属性,
        // 该拷贝副本取代mdb用于后续的操作
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }
 
    // Prepare method overrides.
    try {
    
    
        // 2.验证及准备覆盖的方法(对override属性进行标记及验证)
        mbdToUse.prepareMethodOverrides();
    } 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.
        // 3.实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        // 4.如果bean不为空,则会跳过Spring默认的实例化过程,直接使用返回的bean
        if (bean != null) {
    
    
            return bean;
        }
    } catch (Throwable ex) {
    
    
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }
    // 5.创建Bean实例(真正创建Bean的方法)
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   
    // 6.返回创建的Bean实例
    return beanInstance;
}

2.1.1 doCreateBean()

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
        throws BeanCreationException {
    
    
 
    // Instantiate the bean.
    // 1.新建Bean包装类
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    
    
        // 1.1 如果是FactoryBean,则需要先移除未完成的FactoryBean实例的缓存
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
    
    
        // 1.2 根据beanName、mbd、args,使用对应的策略创建Bean实例,并返回包装类BeanWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 4.拿到创建好的Bean实例
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    // 5.拿到Bean实例的类型
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    mbd.resolvedTargetType = beanType;
 
    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
    
    
        if (!mbd.postProcessed) {
    
    
            try {
    
    
                // 6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition,
                // Autowired注解正是通过此方法实现注入类型的预解析
                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.
    // 7.判断是否需要提早曝光实例:单例 && 允许循环依赖 && 当前bean正在创建中
    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");
        }
 
        // 8.提前曝光beanName的ObjectFactory,用于解决循环引用
        addSingletonFactory(beanName, new ObjectFactory<Object>() {
    
    
            @Override
            public Object getObject() throws BeansException {
    
    
                // 8.1 应用后置处理器SmartInstantiationAwareBeanPostProcessor,允许返回指定bean的早期引用,若没有则直接返回bean
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }
 
    // Initialize the bean instance.  初始化bean实例。
    Object exposedObject = bean;
    try {
    
    
        // 9.对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
    
    
            // 10.对bean进行初始化
            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);
        }
    }
 
    if (earlySingletonExposure) {
    
    
        // 11.如果允许提前曝光实例,则进行循环依赖检查
        Object earlySingletonReference = getSingleton(beanName, false);
        // 11.1 earlySingletonReference只有在当前解析的bean存在循环依赖的情况下才会不为空
        if (earlySingletonReference != null) {
    
    
            if (exposedObject == bean) {
    
    
                // 11.2 如果exposedObject没有在initializeBean方法中被增强,则不影响之前的循环引用
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    
    
                // 11.3 如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例
                // && 当前bean有被其他bean依赖
 
                // 11.4 拿到依赖当前bean的所有bean的beanName数组
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
    
    
                    // 11.5 尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
    
    
                        // 11.6 移除失败的添加到 actualDependentBeans
                        actualDependentBeans.add(dependentBean);
                    }
                }
 
                if (!actualDependentBeans.isEmpty()) {
    
    
                    // 11.7 如果存在移除失败的,则抛出异常,因为存在bean依赖了“脏数据”
                    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.");
                }
            }
        }
    }
 
    // Register bean as disposable.
    try {
    
    
        // 12.注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
    
    
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    // 13.完成创建并返回
    return exposedObject;
}

1.新建Bean包装类

  • 1.1 优先从FactoryBean实例的缓存中查找
  • 1.2 根据beanName、mbd、args,使用对应的策略创建Bean实例,调用createBeanInstance(),核心方法,后面会介绍

6.应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition,Autowired注解正是通过此方法实现注入类型的预解析

9.对bean进行属性填充;其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean实例

10.对bean进行初始化

12.注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor

2.1.1.1 createBeanInstance()

就是生成一个实例,内部是反射,当然初始结果是一个Wrapper实例,通过getWrappedInstance()可以获取原始的bean对象:

instanceWrapper = createBeanInstance(beanName, mbd, args);
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);

2.1.1.2 populateBean()

在完成Bean实例化后,Spring容器会给这个Bean注入相关的依赖Bean,在源码中,这一步通过类AbstractAutowireCapableBeanFactory中的populateBean方法完成。

即@Autowired的处理

参见:
《populateBean实现 依赖注入源码解析》
《populateBean()方法对@Autowired和@Value注解的处理》

2.1.1.3 initializeBean()

初始化bean,正好是生命周期的逻辑:
在这里插入图片描述

2.1.1.3.1 Spring Bean的生命周期

完整步骤如下,步骤2对应<2.1.1.2 populateBean()>章节,步骤3-9对应<2.1.1.3 initializeBean()>章节:

  1. 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为
    连Autowired注解都是没有解析的;
  2. 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
  3. 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
  4. 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
  5. 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
  6. 调用BeanPostProcessor的postProcessBeforeInitialization方法;
  7. 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
  8. 如果Bean定义了init-method方法,则调用Bean的init-method方法;
  9. 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的
    上下文中,直到被销毁;
  10. 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用。

参考:《Spring IoC源码学习:getBean 详解》

猜你喜欢

转载自blog.csdn.net/m0_45406092/article/details/115007108
今日推荐