Spring源码-Bean的生命周期

Posted AC_Jobim

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring源码-Bean的生命周期相关的知识,希望对你有一定的参考价值。

Spring源码-Bean的生命周期

一、finishBeanFactoryInitialization(beanFactory)

实例化所有剩余的非懒加载单例,比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。实例化的过程各种BeanPostProcessor开始起作用。

  • finishBeanFactoryInitialization(beanFactory):

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) 
        // Initialize conversion service for this context.
        // 1.初始化此上下文的转换服务
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) 
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        
     
        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        // 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
        if (!beanFactory.hasEmbeddedValueResolver()) 
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() 
                @Override
                public String resolveStringValue(String strVal) 
                    return getEnvironment().resolvePlaceholders(strVal);
                
            );
        
     
        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        // 3.初始化LoadTimeWeaverAware Bean实例对象
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) 
            getBean(weaverAwareName);
        
     
        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);
     
        // Allow for caching all bean definition metadata, not expecting further changes.
        // 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
        beanFactory.freezeConfiguration();
     
        // Instantiate all remaining (non-lazy-init) singletons.
        // 5.实例化所有剩余(非懒加载)单例对象
        beanFactory.preInstantiateSingletons();
    
    

1.1 preInstantiateSingletons()

  • preInstantiateSingletons()

    @Override
    public void F() throws BeansException 
        if (this.logger.isDebugEnabled()) 
            this.logger.debug("Pre-instantiating singletons in " + this);
        
     
        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        // 1.创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
        List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
     
        // Trigger initialization of all non-lazy singleton beans...
        // 2.遍历beanNames,触发所有非懒加载单例bean的初始化
        for (String beanName : beanNames) 
            // 3.获取beanName对应的MergedBeanDefinition
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 4.bd对应的Bean实例:不是抽象类 && 是单例 && 不是懒加载
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) 
                // 5.判断beanName对应的bean是否为FactoryBean
                if (isFactoryBean(beanName)) 
                    // 5.1.1 通过beanName获取FactoryBean实例
                    // 通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例
                    final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    // 5.1.2 判断这个FactoryBean是否希望急切的初始化
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) 
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() 
                            @Override
                            public Boolean run() 
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            
                        , getAccessControlContext());
                     else 
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    
                    if (isEagerInit) 
                        // 5.1.3 如果希望急切的初始化,则通过beanName获取bean实例
                        getBean(beanName);
                    
                 else 
                    // 5.2.1 如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
                    getBean(beanName);
                
            
        
     
        // Trigger post-initialization callback for all applicable beans...
        // 6.遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
        for (String beanName : beanNames) 
            // 6.1 拿到beanName对应的bean实例
            Object singletonInstance = getSingleton(beanName);
            // 6.2 判断singletonInstance是否实现了SmartInitializingSingleton接口
            if (singletonInstance instanceof SmartInitializingSingleton) 
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                // 6.3 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
                if (System.getSecurityManager() != null) 
                    AccessController.doPrivileged(new PrivilegedAction<Object>() 
                        @Override
                        public Object run() 
                            smartSingleton.afterSingletonsInstantiated();
                            return null;
                        
                    , getAccessControlContext());
                 else 
                    smartSingleton.afterSingletonsInstantiated();
                
            
        
    
    

这个方法主要是循环遍历BeanDefinitionMap, 调用getBean, 去生产bean:

  1. 创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义

  2. 遍历beanNames,触发所有非懒加载单例bean的初始化

  3. 获取beanName对应的MergedBeanDefinition

  4. bd对应的Bean实例:不是抽象类 && 是单例 && 不是懒加载

  5. 判断beanName对应的bean是否为FactoryBean

    1. 是FactoryBean类型
      1. 通过beanName获取FactoryBean实例
      2. 判断这个FactoryBean是否希望急切的初始化
      3. 如果希望急切的初始化,则通过beanName获取bean实例
    2. 不是FactoryBean类型
      1. 通过get(beanName)获取bean实例(核心)
  6. 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调

二、getBean(name)方法

  • 该方法是一个空壳方法,没有任何的实现逻辑 真正的逻辑调用在doGetBean()中

    @Override
    public Object getBean(String name) throws BeansException 
       //真正的获取bean的逻辑
       return doGetBean(name, null, null, false);
    
    

三、doGetBean(name, null, null, false)方法

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;
 
    // Eagerly check singleton cache for manually registered singletons.
    // 2.尝试从缓存中获取beanName对应的实例
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) 
        // 如果beanName的实例存在于缓存中
        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 + "'");
            
        
        // 3.返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
     else 
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        // 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.
        // 获取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) 
            // 如果不是仅仅做类型检测,而是创建bean实例,这里要将beanName放到alreadyCreated缓存
            markBeanAsCreated(beanName);
        
 
        try 
            // 根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 检查MergedBeanDefinition
            checkMergedBeanDefinition(mbd, beanName, args);
 
            // Guarantee initialization of beans that the current bean depends on.
            // 6.拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) 
                // 6.1 遍历当前bean依赖的bean名称集合
                for (String dep : dependsOn) 
                    // 6.2 检查dep是否依赖于beanName,即检查是否存在循环依赖
                    if (isDependent(beanName, dep)) 
                        // 6.3 如果是循环依赖则抛异常
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    
                    // 6.4 将dep和beanName的依赖关系注册到缓存中
                    registerDependentBean(dep, beanName);
                    // 6.5 获取dep对应的bean实例,如果dep还没有创建bean实例,则创建dep的bean实例
                    getBean(dep);
                
            
 
            // Create bean instance.
            // 7.创建单例bean
            if (mbd.isSingleton()) 
                // 7.1 把beanName 和一个singletonFactory传入一个回调对象用于回调
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() 
                    @Override
                    public Object getObject() throws BeansException     //
                        try 
                            // 创建Bean实例
                            return createBean(beanName, mbd, args);
                         catch (BeansException ex) 
                            //创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
                            destroySingleton(beanName);
                            throw ex;
                        
                    
                );
                // 返回beanName对应的实例对象
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
             else if (mbd.isPrototype()) 
                // scope为prototype的bean创建
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try 
                    // 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
                    beforePrototypeCreation(beanName);
                    // 创建Bean实例
                    prototypeInstance = createBean(beanName, mbd, args);
                 finally 
                    // 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
                    afterPrototypeCreation(beanName);
                
                // 返回beanName对应的实例对象
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
             else 
                // 其他scope的bean创建,可能是request之类的
                // 根据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 
                    // 其他scope的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() 
                        @Override
                        public Object getObject() throws BeansException 
                            // 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
                            beforePrototypeCreation(beanName);
                            try 
                                // 创建bean实例
                                return createBean(beanName, mbd, args);
                             finally 
                                // 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
                                afterPrototypeCreation(beanName);
                            
                        
                    );
                    // 返回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.
    // 检查所需类型是否与实际的bean对象的类型匹配
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) 
        try 
            // 类型不对,则尝试转换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());
        
    
    // 返回创建出来的bean实例对象
    return (T) bean;

  1. transformedBeanName(name),解析 beanName,主要是解析别名、去掉 FactoryBean 的修饰符 “&”。

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

  3. 如果beanName的实例存在于缓存中,则返回beanName对应的实例对象(主要用于FactoryBean的特殊处理,普通Bean会直接返回sharedInstance本身)

  4. scope为prototype的循环依赖校验:如果beanName已经正在创建Bean实例中,而此时我们又要再一次创建beanName的实例,则代表出现了循环依赖,需要抛出异常

  5. 如果parentBeanFactory(父工厂)存在,并且beanName在当前BeanFactory不存在Bean定

    以上是关于Spring源码-Bean的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

    Spring 框架源码 Bean的生命周期全流程源码解析

    Spring源码-Bean的生命周期

    Spring源码-Bean的生命周期

    Spring源码-Bean的生命周期

    Spring源码解读---Bean生命周期源码解析

    Spring源码解读---Bean生命周期源码解析