AI智能
改变未来

Spring Bean生命周期

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有一个实现,代码如下所示:

@Overrideprotected 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));//初始化XmlBeanDefinitionReaderinitBeanDefinitionReader(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,BeanDefinitionRead8gistry是一个接口,一个典型的实现类是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<String> 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;}
   ad8  //判断是否存在这个配置且已经创建单例Beanif (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获取合并后的BeanDefinitionif (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);}//从当前BeanFactory获取合并后的BeanDefintionreturn getMergedLocalBeanDefinition(beanName);}
protected RootBea1b1cnDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {//从缓存里获取RootBeanDefinitionRootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
     //如果不是空并且不需要再次合并,返回缓存的RootBeanDefinitionif (mbd != null && !mbd.stale) {return mbd;}
     //返回合并的BeanDefinition,入参是beanName、GenericBeanDefinitionreturn 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;//加锁后再从缓存里查询一次,dclif (containingBd == null) {mbd = this.mergedBeanDefinitions.get(beanName);}
       //如果获取不到或者需要再次合并,执行合并BeanDefinition逻辑if (mbd == null || mbd.stale) {previous = mbd;if (bd.getParentName() == null) {//如果没有父beanName,直接生成RootBeanDefinitionif (bd instanceof RootBeanDefinition) {mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();}else {mbd = new RootBeanDefinition(bd);}}else {//如果有父beanName,需要用父BeanDefinition合并生成RootBeanDefinitionBeanDefinition pbd;try {String parentBeanName = transformedBeanName(bd.getParentName());if (!beanName.equals(parentBeanName)) {
                 //用parentBeanName获取BeanDefinitionpbd = 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创建RootBeanDefinitionmbd = new RootBeanDefinition(pbd);
           //用子BeanDefinition覆盖RootBeanDefinitionmbd.overrideFrom(bd);}//设置scopeif (!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) {
         //加载对应classreturn AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());}else {
         //加载对应classreturn 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(), beanName56c, 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不是空,动态类加载器设置为tempClassLoaderClassLoader tempClassLoader = getTempClassLoader();ad8if (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)) {//如果evaluateBeanDefinitionStringif (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使用默认类加载器并且关联到RootBeanDefinitionreturn mbd.resolveBeanClass(beanClassLoader);}

Spring Bean实例化阶段

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

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {//使用RootBeanDefinition加载classClass<?> 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方式实例化BeanSupplier<?> 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 =56cmbd.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()ad8|| !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<PropertyValue> 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<PropertyValue> 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<Object>) () -> {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方法初始化Beanboolean 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<Object>) () -> {((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销毁操作会销毁BeanScope 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));}}}
publicbe8void 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<Object>) () -> {((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垃圾收集。

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Spring Bean生命周期