Spring Bean生命周期

java1234

共 11494字,需浏览 23分钟

 ·

2021-02-20 10:17

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

  作者 |  Gouden

来源 |  urlify.cn/2QZr6f

76套java从入门到精通实战课程分享

Spring Bean生命周期整体可分为以下几个阶段:

  • Spring Bean元信息处理阶段

  • Spring Bean实例化阶段

  • Spring Bean初始化阶段

  • Spring Bean销毁阶段

  • Spring Bean垃圾收集阶段

Spring Bean生命周期处理是Spring应用上下文生命周期的一部分,可以参考此文了解Spring应用上下文生命周期。

Spring Bean元信息处理阶段

Spring Bean元信息处理阶段可以细分为以下几个阶段:

  • Spring Bean元信息解析阶段

  • Spring BeanDefinition注册阶段

  • Spring BeanDefinition合并阶段

Spring Bean元信息解析阶段

在Spring应用上下文生命周期里有一个创建BeanFactory阶段,在这个阶段会创建底层IoC容器BeanFactory,然后会进行一些别的操作,其中一个操作就是处理Spring Bean元信息,代码如下所示:

protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

可以看出这个方法会调用方法loadBeanDefinitions加载Spring Bean元信息: BeanDefinition。

loadBeanDefinitions在子类AbstractXmlApplicationContext有一个实现,代码如下所示:

@Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        //创建XmlBeanDefinitionReader解析XML配置文件读取Spring Bean元信息
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        //设置Spring Bean元信息读取配置
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        //初始化XmlBeanDefinitionReader
        initBeanDefinitionReader(beanDefinitionReader);     //加载Spring Bean元信息
        loadBeanDefinitions(beanDefinitionReader);
    }
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {     //获取资源配置
        Resource[] configResources = getConfigResources();     //如果不是空,加载对应资源
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }     //获取资源配置字符串,是路径
        String[] configLocations = getConfigLocations();     //如果不是空,加载对应资源
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }

这一块代码逻辑比较简单,就是使用XmlBeanDefinitionReader加载Spring Bean元信息,这里指处理了XML配置的元信息。

还有一种常用Spring Bean元信息配置是注解,针对这种Spring Bean元信息配置的解析,在AnnotationConfigApplicationContext进行处理,代码如下所示:

    public AnnotationConfigApplicationContext(String... basePackages) {
        this();
        scan(basePackages);
        refresh();
    }

AnnotationConfigApplicationContext一个构造器里会调用scan方法扫描指定包路径,会使用ClassPathBeanDefinitionScanner的scan能力扫描具有某些注解的类,把这些类加载为Spring Bean元信息。

Spring BeanDefinition注册阶段

上面着重介绍了Spring Bean元信息解析,Spring Bean元信息解析之后,就要注册并保存起来,方便后续使用。

Spring具有一个数据结构BeanDefinitionRegistry,解析后的BeanDefinition会注册到BeanDefinitionRegistry,BeanDefinitionRegistry是一个接口,一个典型的实现类是DefaultListableBeanFactory。

DefaultListableBeanFactory里的registerBeanDefinition方法实现如下所示(这里删除了一些打印日志分支):

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
     //校验入参
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
         //判断BeanDefinition是否是AbstractBeanDefinition类或子类的对象,如果是,进行校验
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }
     //判断beanName对应BeanDefinition是否存在
        BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);     //如果已经存在,判断是否允许覆盖,这里覆盖是指一个beanName有两个不同BeanDefinition,默认允许
        if (existingDefinition != null) {        //如果不允许覆盖,抛出异常
            if (!isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }        //如果允许覆盖,覆盖配置
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        else {        //判断是否已经有Bean被创建了
            if (hasBeanCreationStarted()) {
                //如果是就不能修改之前集合,需要全量覆盖
                synchronized (this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    removeManualSingletonName(beanName);
                }
            }
            else {
                //如果不是就修改之前集合
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                removeManualSingletonName(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }
     //判断是否存在这个配置且已经创建单例Bean
        if (existingDefinition != null || containsSingleton(beanName)) {        //如果是就清除缓存
            resetBeanDefinition(beanName);
        }
    }

Spring BeanDefinition合并阶段

Spring BeanDefinition在用来实例化前,还需要做的一件事就是Spring BeanDefinition合并。

在底层IoC容器通常会有两种BeanDefinition,一个是GenericBeanDefinition,一个是RootBeanDefinition,一个Bean在实例化前,对应BeanDefinition都要转化成RootBeanDefinition。

GenericBeanDefinition保存原始的Spring Bean元信息,可以指定父Bean的beanName,但是不会继承父Bean的属性,还不具备实例化的能力。

GenericBeanDefinition在合并之后会变成RootBeanDefinition,这时RootBeanDefinition不会保存父Bean的beanName,但是会从父Bean继承属性。

就算一个GenericBeanDefinition没有父Bean也需要转换成RootBeanDefinition。

BeanDefinition合并操作通常在实例化前进行,ConfigurableBeanFactory#getMergedBeanDefinition方法会合并对应BeanDefinition并且返回,getMergedBeanDefinition(AbstractBeanFactory)代码如下所示:

public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
        String beanName = transformedBeanName(name);
        //判断当前BeanFactory不存在对应BeanDefinition,从父BeanFactory获取合并后的BeanDefinition
        if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
            return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
        }
        //从当前BeanFactory获取合并后的BeanDefintion
        return getMergedLocalBeanDefinition(beanName);
    }
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
        //从缓存里获取RootBeanDefinition
        RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);     //如果不是空并且不需要再次合并,返回缓存的RootBeanDefinition
        if (mbd != null && !mbd.stale) {
            return mbd;
        }     //返回合并的BeanDefinition,入参是beanName、GenericBeanDefinition
        return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    }

最后会进到下面这个方法:

protected RootBeanDefinition getMergedBeanDefinition(
            String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
            throws BeanDefinitionStoreException {

        synchronized (this.mergedBeanDefinitions) {
            RootBeanDefinition mbd = null;
            RootBeanDefinition previous = null;

            //加锁后再从缓存里查询一次,dcl
            if (containingBd == null) {
                mbd = this.mergedBeanDefinitions.get(beanName);
            }
        //如果获取不到或者需要再次合并,执行合并BeanDefinition逻辑
            if (mbd == null || mbd.stale) {
                previous = mbd;
                if (bd.getParentName() == null) {
                    //如果没有父beanName,直接生成RootBeanDefinition
                    if (bd instanceof RootBeanDefinition) {
                        mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                    }
                    else {
                        mbd = new RootBeanDefinition(bd);
                    }
                }
                else {
                    //如果有父beanName,需要用父BeanDefinition合并生成RootBeanDefinition
                    BeanDefinition pbd;
                    try {
                        String parentBeanName = transformedBeanName(bd.getParentName());
                        if (!beanName.equals(parentBeanName)) {                 //用parentBeanName获取BeanDefinition
                            pbd = getMergedBeanDefinition(parentBeanName);
                        }
                        else {
                            BeanFactory parent = getParentBeanFactory();
                            if (parent instanceof ConfigurableBeanFactory) {
                                pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                            }
                            else {
                                throw new NoSuchBeanDefinitionException(parentBeanName,
                                        "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                                        "': cannot be resolved without an AbstractBeanFactory parent");
                            }
                        }
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                                "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
                    }
                    //用parentBeanName获取RootBeanDefinition创建RootBeanDefinition
                    mbd = new RootBeanDefinition(pbd);             //用子BeanDefinition覆盖RootBeanDefinition
                    mbd.overrideFrom(bd);
                }

                //设置scope
                if (!StringUtils.hasLength(mbd.getScope())) {
                    mbd.setScope(SCOPE_SINGLETON);
                }

                if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                    mbd.setScope(containingBd.getScope());
                }

                //把RootBeanDefinition放到缓存
                if (containingBd == null && isCacheBeanMetadata()) {
                    this.mergedBeanDefinitions.put(beanName, mbd);
                }
            }
            if (previous != null) {
                copyRelevantMergedBeanDefinitionCaches(previous, mbd);
            }
            return mbd;
        }
    }

Spring Bean实例化阶段

Spring Bean实例化阶段可以细分为以下几个阶段:

  • Spring Bean Class加载阶段

  • Spring Bean实例化阶段

  • Spring Bean实例化前阶段

  • Spring Bean实例化后阶段

  • Spring Bean属性赋值前阶段

  • Spring Bean赋值阶段

Spring Bean Class加载阶段

Spring Bean Class加载方法是AbstractBeanFactory#resolveBeanClass,代码如下所示:

 resolveBeanClass方法会使用RootBeanDefinition里记录的beanClassName加载对应类,保存到RootBeanDefinition并且返回。

protected Class resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class... typesToMatch)
            throws CannotLoadBeanClassException {

        try {
            if (mbd.hasBeanClass()) {          //判断RootBeanDefinition里关联了class,直接返回
                return mbd.getBeanClass();
            }
            if (System.getSecurityManager() != null) {          //加载对应class
                return AccessController.doPrivileged((PrivilegedExceptionAction>) () ->
                    doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
            }
            else {          //加载对应class
                return doResolveBeanClass(mbd, typesToMatch);
            }
        }
        catch (PrivilegedActionException pae) {
            ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
        }
        catch (ClassNotFoundException ex) {
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
        }
        catch (LinkageError err) {
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
        }
    }
private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch)
            throws ClassNotFoundException {
     //获取当前类加载器
        ClassLoader beanClassLoader = getBeanClassLoader();     //定义动态类加载器,默认是上面的类加载器,可以修改扩展
        ClassLoader dynamicLoader = beanClassLoader;
        boolean freshResolve = false;

        if (!ObjectUtils.isEmpty(typesToMatch)) {
            //如果tempClassLoader不是空,动态类加载器设置为tempClassLoader
            ClassLoader tempClassLoader = getTempClassLoader();
            if (tempClassLoader != null) {
                dynamicLoader = tempClassLoader;
                freshResolve = true;
                if (tempClassLoader instanceof DecoratingClassLoader) {
                    DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
                    for (Class typeToMatch : typesToMatch) {
                        dcl.excludeClass(typeToMatch.getName());
                    }
                }
            }
        }

        String className = mbd.getBeanClassName();
        if (className != null) {
            Object evaluated = evaluateBeanDefinitionString(className, mbd);
            if (!className.equals(evaluated)) {
                //如果evaluateBeanDefinitionString
                if (evaluated instanceof Class) {
                    return (Class) evaluated;
                }
                else if (evaluated instanceof String) {
                    className = (String) evaluated;
                    freshResolve = true;
                }
                else {
                    throw new IllegalStateException("Invalid class name expression result: " + evaluated);
                }
            }
            if (freshResolve) {
                //使用dynamicLoader加载class并且不和RootBeanDefinition关联,目前没有用到过,后面确认用处
                if (dynamicLoader != null) {
                    try {
                        return dynamicLoader.loadClass(className);
                    }
                    catch (ClassNotFoundException ex) {
                        if (logger.isTraceEnabled()) {
                            logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
                        }
                    }
                }
                return ClassUtils.forName(className, dynamicLoader);
            }
        }

        //常规处理方式,RootBeanDefinition使用默认类加载器并且关联到RootBeanDefinition
        return mbd.resolveBeanClass(beanClassLoader);
    }

Spring Bean实例化阶段

AbstractAutowireCapableBeanFactory#createBeanInstance方法处理Spring Bean实例化,给指定beanName创建一个新的实例,先后使用工厂方法、构造器自动注入、简单实例化方式创建,具体代码如下所示: 

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        //使用RootBeanDefinition加载class
        Class beanClass = resolveBeanClass(mbd, beanName);
     //如果访问不到这个类,抛出异常
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }
     //配置lamda方式实例化Bean
        Supplier instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }
     //如果是工厂方式,用工厂方式实例化对象
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        //如果某个RootBeanDefinition已经实例化过再次实例化,直接使用上次配置,不需要再决策
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                return instantiateBean(beanName, mbd);
            }
        }

        //决策候选构造器
        Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        //获取合适构造器
        ctors = mbd.getPreferredConstructors();
        if (ctors != null) {
            return autowireConstructor(beanName, mbd, ctors, null);
        }

        //使用无参构造器实例化对象
        return instantiateBean(beanName, mbd);
    }

Spring Bean实例化前阶段

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation方法提供一个扩展方式可以让Spring Bean在实例化前做一些扩展,比如一些RPC场景,可以在这里生成RPC接口代理类,不执行实例化逻辑,具体代码如下所示:

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            //如果有InstantiationAwareBeanPostProcessors,调用applyBeanPostProcessorsBeforeInstantiation方法获取对象
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }
protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;          //调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法创建对象
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

Spring Bean实例化后阶段

AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors方法是Spring提供的第一个Spring Bean实例化后扩展,实现MergedBeanDefinitionPostProcessor接口即可进行扩展,具体代码如下所示:

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class beanType, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof MergedBeanDefinitionPostProcessor) {
         MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
         bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
      }
   }
}

Spring提供的第二个实例化后扩展是InstantiationAwareBeanPostProcessor,在方法AbstractAutowireCapableBeanFactory#populateBean里有一段代码处理这个扩展,具体代码如下所示:

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
         }
      }
   }
}

Spring Bean赋值前阶段

Spring Bean赋值前提供扩展是InstantiationAwareBeanPostProcessor#postProcessProperties和InstantiationAwareBeanPostProcessor#postProcessPropertyValues,在方法AbstractAutowireCapableBeanFactory#populateBean里有一段代码处理这两个扩展,具体代码如下所示:

if (hasInstAwareBpps) {
   if (pvs == null) {
      pvs = mbd.getPropertyValues();
   }
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
         if (pvsToUse == null) {
            if (filteredPds == null) {
               filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               return;
            }
         }
         pvs = pvsToUse;
      }
   }
}

Spring Bean赋值阶段

Spring Bean赋值阶段代码如下所示:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
   if (pvs.isEmpty()) {
      return;
   }

   if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
      ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
   }

   MutablePropertyValues mpvs = null;
   List original;

   if (pvs instanceof MutablePropertyValues) {
      mpvs = (MutablePropertyValues) pvs;
      if (mpvs.isConverted()) {
         // Shortcut: use the pre-converted values as-is.
         try {
            bw.setPropertyValues(mpvs);
            return;
         }
         catch (BeansException ex) {
            throw new BeanCreationException(
                  mbd.getResourceDescription(), beanName, "Error setting property values", ex);
         }
      }
      original = mpvs.getPropertyValueList();
   }
   else {
      original = Arrays.asList(pvs.getPropertyValues());
   }

   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }
   BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

   // Create a deep copy, resolving any references for values.
   List deepCopy = new ArrayList<>(original.size());
   boolean resolveNecessary = false;
   for (PropertyValue pv : original) {
      if (pv.isConverted()) {
         deepCopy.add(pv);
      }
      else {
         String propertyName = pv.getName();
         Object originalValue = pv.getValue();
         if (originalValue == AutowiredPropertyMarker.INSTANCE) {
            Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
            if (writeMethod == null) {
               throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
            }
            originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
         }
         Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
         Object convertedValue = resolvedValue;
         boolean convertible = bw.isWritableProperty(propertyName) &&
               !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
         if (convertible) {
            convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
         }
         // Possibly store converted value in merged bean definition,
         // in order to avoid re-conversion for every created bean instance.
         if (resolvedValue == originalValue) {
            if (convertible) {
               pv.setConvertedValue(convertedValue);
            }
            deepCopy.add(pv);
         }
         else if (convertible && originalValue instanceof TypedStringValue &&
               !((TypedStringValue) originalValue).isDynamic() &&
               !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
            pv.setConvertedValue(convertedValue);
            deepCopy.add(pv);
         }
         else {
            resolveNecessary = true;
            deepCopy.add(new PropertyValue(pv, convertedValue));
         }
      }
   }
   if (mpvs != null && !resolveNecessary) {
      mpvs.setConverted();
   }

   // Set our (possibly massaged) deep copy.
   try {
      bw.setPropertyValues(new MutablePropertyValues(deepCopy));
   }
   catch (BeansException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
   }
}

Spring Bean初始化阶段

Spring Bean初始化阶段可以细分为以下几个阶段:

  • Spring Bean Aware接口回调阶段

  • Spring Bean初始化前阶段

  • Spring Bean初始化阶段

  • Spring Bean初始化后阶段

Spring Bean初始化代码如下所示:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {   //Spring Bean Aware接口回调
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;   //Spring Bean初始化前阶段
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }
   //Spring Bean初始化阶段
   try {
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }   //Spring Bean初始化后阶段
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

Spring Bean Aware接口回调阶段

invokeAwareMethods具体代码如下所示:

private void invokeAwareMethods(final String beanName, final Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
        }
    }

Spring Bean初始化前阶段

applyBeanPostProcessorsBeforeInitialization具体代码如下所示:

这个方法会调用BeanPostProcessor#postProcessBeforeInitialization方法。

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

Spring Bean初始化阶段

invokeInitMethods具体代码如下所示:

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {
     //处理InitializingBean#afterPropertiesSet方法初始化Bean
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }
     //处理自定义初始化方法
        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

Spring Bean初始化后阶段

applyBeanPostProcessorsAfterInitialization具体代码如下所示:

这个方法回调用BeanPostProcessor#postProcessAfterInitialization方法。

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

Spring Bean销毁阶段

Spring Bean销毁阶段可以细分为以下几个阶段:

  • Spring Bean销毁前阶段

  • Spring Bean销毁阶段

Spring Bean在初始化后会调用registerDisposableBeanIfNecessary方法注册到disposableBeans,方便后续销毁。

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
        AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
        if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
            if (mbd.isSingleton()) {
                //注册DisposableBeanAdapter,后续销毁时用
                registerDisposableBean(beanName,
                        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
            }
            else {
                //如果不是单例而且不是原生,比如servlet里context、request等作用域,在一定阶段触发scope销毁操作会销毁Bean
                Scope scope = this.scopes.get(mbd.getScope());
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
                }
                scope.registerDestructionCallback(beanName,
                        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
            }
        }
    }
public void destroy() {     //Spring销毁前阶段,调动DestructionAwareBeanPostProcessor#postProcessBeforeDestruction方法
        if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
            for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
                processor.postProcessBeforeDestruction(this.bean, this.beanName);
            }
        }
     //调用DisposableBean#destroy方法
        if (this.invokeDisposableBean) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
            }
            try {
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
                        ((DisposableBean) this.bean).destroy();
                        return null;
                    }, this.acc);
                }
                else {
                    ((DisposableBean) this.bean).destroy();
                }
            }
            catch (Throwable ex) {
                String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
                if (logger.isDebugEnabled()) {
                    logger.warn(msg, ex);
                }
                else {
                    logger.warn(msg + ": " + ex);
                }
            }
        }
     //调用自定义销毁函数
        if (this.destroyMethod != null) {
            invokeCustomDestroyMethod(this.destroyMethod);
        }
        else if (this.destroyMethodName != null) {
            Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
            if (methodToInvoke != null) {
                invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
            }
        }
    }

Spring Bean垃圾收集阶段

Spring Bean在Spring应用上下文关闭后触发GC会触发Spring Bean垃圾收集。





粉丝福利:Java从入门到入土学习路线图

👇👇👇

👆长按上方微信二维码 2 秒


感谢点赞支持下哈 

浏览 21
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报