Spring源码解析:set注入与初始化过程详解?

2026-05-23 05:491阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1318个文字,预计阅读时间需要6分钟。

记录并分享个人学习Spring源码的过程,有任何问题或需要补充的内容,会持续更新。欢迎指正!

环境:- Spring版本:5.X- 开发工具:IDEA

建议:- 学习过程中,建议打开源码,逐步跟踪Spring如何基于BeanDefinition创建单例Bean。

记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正!

环境: spring5.X + idea

建议:学习过程中要开着源码一步一步过

Spring根据BeanDefinition创建单例对象
  1. DefaultSingletonBeanRegistergetSingleton((String beanName, ObjectFactory<?> singletonFactory))

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, ...); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; }catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } }catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; }finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }

解析:

  1. getSingleton 方法中还是先要在单例池中获取将要被创建的对象是不是存在,不存在了才去创建。this.singletonObjects.get(beanName); 如果不存在Spring还会效验一下是不是正在被销毁,是则抛异常。this.singletonsCurrentlyInDestruction
  2. 一系列效验完成后开始正式创建对象的第一步beforeSingletonCreation(beanName);
    创建对象前要满足俩个条件inCreationCheckExclusions&&singletonsCurrentlyInCreation.add(beanName),当前这个Bean没有被排除,并且这个bean正在创建中。
  3. 通过singletonFactory.getObject();回调createBean(beanName, mbd, args);
    创建对象时先获取对应的BeanClass(通过反射创建对象),调用doCreateBean(beanName, mbdToUse, args);,这个方法中才是正儿八经的实例化对象

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; //.... if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } //............. // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); 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) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } doCreateBean解析:

A. 创建对象:createBeanInstance(beanName, mbd, args);

  1. 通过工厂方法创建对象

if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); }

  1. 通过默认的无参构造创建对象

instantiateBean(beanName, mbd);

B. 填充属性:populateBean(beanName, mbd, instanceWrapper); 也是就是Set注入(构造注入已经在创建对象时执行了,自动注入可以忽略)

  1. 注解属性赋值

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; } } }

解析:通过注解对属性填充使用了AutowiredAnnotationBeanPostProcessor实现所有操作,在postProcessProperties(pvs, bw.getWrappedInstance(), beanName);方法中真正实现。

  1. 标签方式属性赋值

if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); }

解析:从RootBeanDefinition中获取属性的List封装到PropertyValues中。
遍历ProperValues 把每个属性的值进行类型转换,最后再给bw设置得到的属性值。-> BeanWrapper.setProperValues(new MutablePropertyValues(deepCopy))。
自定义类型会通过beanFactory.getBean() 获取对应的对象,再走一遍doGetBean() -> createBean() -> doCreateBean()...
(JDK的类型会先封装TypeStringValues。自定义的类型会封装RuntimeBeanReference)

C. 初始化对象:initializeBean(beanName, exposedObject, mbd);

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { ....... } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { ...... } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

解析:初始化分几个功能
1. Aware -> invokeAwareMethods(String beanName, Object bean)。spring提供的帮助我们获取Spring容器中对应的组件的相关信息。
2. BeanPostProcessorsBefore -> applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);已经创建好的对象初始化之前再次加工。
3. 初始化 -> invokeInitMethods(beanName, wrappedBean, mbd);包含了接口初始化((InitializingBean) bean).afterPropertiesSet();和自定义方法初始化invokeCustomInitMethod(beanName, bean, mbd);
4. BeanPostProcessorsAfter -> applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);已经创建好的对象初始化之后再次加工。

最后

感谢您的阅读,有什么意见和问题欢迎评论区留言!书写不易!
觉得文章对你有帮助记得给我点个赞,欢迎大家关注和转发文章!

本文共计1318个文字,预计阅读时间需要6分钟。

记录并分享个人学习Spring源码的过程,有任何问题或需要补充的内容,会持续更新。欢迎指正!

环境:- Spring版本:5.X- 开发工具:IDEA

建议:- 学习过程中,建议打开源码,逐步跟踪Spring如何基于BeanDefinition创建单例Bean。

记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正!

环境: spring5.X + idea

建议:学习过程中要开着源码一步一步过

Spring根据BeanDefinition创建单例对象
  1. DefaultSingletonBeanRegistergetSingleton((String beanName, ObjectFactory<?> singletonFactory))

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, ...); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; }catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } }catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; }finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }

解析:

  1. getSingleton 方法中还是先要在单例池中获取将要被创建的对象是不是存在,不存在了才去创建。this.singletonObjects.get(beanName); 如果不存在Spring还会效验一下是不是正在被销毁,是则抛异常。this.singletonsCurrentlyInDestruction
  2. 一系列效验完成后开始正式创建对象的第一步beforeSingletonCreation(beanName);
    创建对象前要满足俩个条件inCreationCheckExclusions&&singletonsCurrentlyInCreation.add(beanName),当前这个Bean没有被排除,并且这个bean正在创建中。
  3. 通过singletonFactory.getObject();回调createBean(beanName, mbd, args);
    创建对象时先获取对应的BeanClass(通过反射创建对象),调用doCreateBean(beanName, mbdToUse, args);,这个方法中才是正儿八经的实例化对象

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; //.... if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } //............. // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); 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) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } doCreateBean解析:

A. 创建对象:createBeanInstance(beanName, mbd, args);

  1. 通过工厂方法创建对象

if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); }

  1. 通过默认的无参构造创建对象

instantiateBean(beanName, mbd);

B. 填充属性:populateBean(beanName, mbd, instanceWrapper); 也是就是Set注入(构造注入已经在创建对象时执行了,自动注入可以忽略)

  1. 注解属性赋值

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; } } }

解析:通过注解对属性填充使用了AutowiredAnnotationBeanPostProcessor实现所有操作,在postProcessProperties(pvs, bw.getWrappedInstance(), beanName);方法中真正实现。

  1. 标签方式属性赋值

if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); }

解析:从RootBeanDefinition中获取属性的List封装到PropertyValues中。
遍历ProperValues 把每个属性的值进行类型转换,最后再给bw设置得到的属性值。-> BeanWrapper.setProperValues(new MutablePropertyValues(deepCopy))。
自定义类型会通过beanFactory.getBean() 获取对应的对象,再走一遍doGetBean() -> createBean() -> doCreateBean()...
(JDK的类型会先封装TypeStringValues。自定义的类型会封装RuntimeBeanReference)

C. 初始化对象:initializeBean(beanName, exposedObject, mbd);

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { ....... } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { ...... } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

解析:初始化分几个功能
1. Aware -> invokeAwareMethods(String beanName, Object bean)。spring提供的帮助我们获取Spring容器中对应的组件的相关信息。
2. BeanPostProcessorsBefore -> applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);已经创建好的对象初始化之前再次加工。
3. 初始化 -> invokeInitMethods(beanName, wrappedBean, mbd);包含了接口初始化((InitializingBean) bean).afterPropertiesSet();和自定义方法初始化invokeCustomInitMethod(beanName, bean, mbd);
4. BeanPostProcessorsAfter -> applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);已经创建好的对象初始化之后再次加工。

最后

感谢您的阅读,有什么意见和问题欢迎评论区留言!书写不易!
觉得文章对你有帮助记得给我点个赞,欢迎大家关注和转发文章!