摘要:前言这篇是专题初始化的第二篇,主要对初始化具体过程的源码分析。上篇博客专题之初始化源码分析中我们对如何开始初始化以及初始化的总体过程有了大致的了解,接下来就继续上篇博客的结尾处开始来分析初始化的具体过程。
前言
这篇是Spring专题Bean初始化的第二篇,主要对bean初始化具体过程的源码分析。上篇博客Spring专题之Bean初始化源码分析(1)中我们对Spring如何开始初始化bean以及bena初始化的总体过程有了大致的了解,接下来就继续上篇博客的结尾处开始来分析初始化bean的具体过程。
Bean初始化上篇博客中我们知道了Spring在通过判断bean定义是否是单例bean,是否是原型bena之后,最后都是调用了createBean方法去创建bean的,所以我们进入该方法分析具体初始化过程。进入方法后发现是该方法是AbstractBeanFactory的一个抽象方法,真正地调用是在子类AbstractAutowireCapableBeanFactory中重写了。源码如下:
//创建Bean实例对象 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean "" + beanName + """); } RootBeanDefinition mbdToUse = mbd; //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载 Class> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } //校验和准备Bean中的方法覆盖 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //创建Bean的入口 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean "" + beanName + """); } return beanInstance; } catch (BeanCreationException ex) { throw ex; } catch (ImplicitlyAppearedSingletonException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
这里我们有两个地方需要了解的,第一个是resolveBeforeInstantiation方法,第二个是doCreateBean方法。之后我们重点分析doCreateBean方法,这里的resolveBeforeInstantiation方法主要是针对Bean如果配置了初始化前和初始化后的处理器,会试图返回一个需要创建Bean的代理对象。那么现在我们开始进入doCreateBean方法,源码如下:
//真正创建Bean的方法 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { //封装被创建的Bean对象 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); //获取实例化对象的类型 Class> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } //调用PostProcessor后置处理器 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } //向容器中缓存单例模式的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"); } //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } //Bean对象的初始化,依赖注入在此触发 //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean Object exposedObject = bean; try { //将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象 populateBean(beanName, mbd, instanceWrapper); //初始化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) { //获取指定名称的已注册的单例模式Bean对象 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { //根据名称获取的已注册的Bean和正在实例化的Bean是同一个 if (exposedObject == bean) { //当前实例化的Bean初始化完成 exposedObject = earlySingletonReference; } //当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); SetactualDependentBeans = new LinkedHashSet<>(dependentBeans.length); //获取当前Bean所依赖的其他Bean for (String dependentBean : dependentBeans) { //对依赖Bean进行类型检查 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 " + ""getBeanNamesOfType" with the "allowEagerInit" flag turned off, for example."); } } } } // Register bean as disposable. //注册完成依赖注入的Bean try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
这里有三个方法我们需要注意,第一个createBeanInstance方法,这是bean实例化的第一步,第二个是populateBean方法,这是bean依赖注入的地方,第三个是initializeBean,这是初始化bean的地方。
首先我们先看createBeanInstance方法,源码如下:
//创建Bean的实例对象 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. //检查确认Bean是可实例化的 Class> beanClass = resolveBeanClass(mbd, beanName); //使用工厂方法对Bean进行实例化 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()); } Supplier> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } if (mbd.getFactoryMethodName() != null) { //调用工厂方法实例化 return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... //使用容器的自动装配方法进行实例化 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) { //配置了自动装配属性,使用容器的自动装配实例化 //容器的自动装配是根据参数类型匹配Bean的构造方法 return autowireConstructor(beanName, mbd, null, null); } else { //使用默认的无参构造方法实例化 return instantiateBean(beanName, mbd); } } // Need to determine the constructor... //使用Bean的构造方法进行实例化 Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { //使用容器的自动装配特性,调用匹配的构造方法实例化 return autowireConstructor(beanName, mbd, ctors, args); } // No special handling: simply use no-arg constructor. //使用默认的无参构造方法实例化 return instantiateBean(beanName, mbd); }
通过上述的源码分析,我们知道Spring这里对bean实例化有几种方式,分别是工厂方法实例化,容器自动装配以及使用默认的无参构造方法实例化。
然后我们在来看populateBean方法是如何进行依赖注入的,源码如下:
//将Bean属性设置到生成的实例对象上 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //如果属性存在但是需要注入的对象为空,则抛出异常。 if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. //使得InstantiationAwareBeanPostProcessors有机会在属性注入之前修改bean的状态,例如支持一些属性类型的注入。 boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } //获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); //对依赖注入处理,首先处理autowiring自动装配的依赖注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. //根据Bean名称进行autowiring自动装配处理 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. //根据Bean类型进行autowiring自动装配处理 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } //对非autowiring的属性进行依赖注入处理 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } if (pvs != null) { //对属性进行注入 applyPropertyValues(beanName, mbd, bw, pvs); } }
这里有也有几个方法需要注意,分别是autowireByName、autowireByType以及applyPropertyValues。
我们先来看下autowireByName方法,源码如下:
//根据名称对属性进行自动依赖注入 protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { //对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符串,URL等都是简单属性)进行处理 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { //如果Spring IOC容器中包含指定名称的Bean if (containsBean(propertyName)) { //调用getBean方法向IOC容器索取指定名称的Bean实例,迭代触发属性的初始化和依赖注入 Object bean = getBean(propertyName); //为指定名称的属性赋予属性值 pvs.add(propertyName, bean); //指定名称属性注册依赖Bean名称,进行属性依赖注入 registerDependentBean(propertyName, beanName); if (logger.isDebugEnabled()) { logger.debug("Added autowiring by name from bean name "" + beanName + "" via property "" + propertyName + "" to bean named "" + propertyName + """); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property "" + propertyName + "" of bean "" + beanName + "" by name: no matching bean found"); } } } }
可以看到这里通过找到Bean中非简单属性的属性,比如CharSequence类型、Number类型、Date类型、URL类型、URI类型、Locale类型、Class类型就会忽略,具体可见BeanUtils的isSimpleProperty方法,遍历所有被找到的属性,如果bean定义中包含了属性名,那么先实例化该属性名对应的bean,注册一下当前bean的依赖bean。
然后我们看下根据类型自动装配autowireByType方法的实现,源码如下:
//根据类型对属性进行自动依赖注入 protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { //获取用户定义的类型转换器 TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } //存放解析的要注入的属性 SetautowiredBeanNames = new LinkedHashSet<>(4); //对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符 //URL等都是简单属性)进行处理 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { //获取指定属性名称的属性描述器 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don"t try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. //不对Object类型的属性进行autowiring自动依赖注入 if (Object.class != pd.getPropertyType()) { //获取属性的setter方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. //检查指定类型是否可以被转换为目标对象的类型 boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance()); //创建一个要被注入的依赖描述 DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); //根据容器的Bean定义解析依赖关系,返回所有要被注入的Bean对象 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { //为属性赋值所引用的对象 pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { //指定名称属性注册依赖Bean名称,进行属性依赖注入 registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name "" + beanName + "" via property "" + propertyName + "" to bean named "" + autowiredBeanName + """); } } //释放已自动注入的属性 autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
具体的解析过程主要看resolveDependency方法,这里感兴趣的同学可以研究下具体过程。
最后我们来看下applyPropertyValues方法,源码如下:
//解析并注入依赖属性的过程 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { if (pvs.isEmpty()) { return; } //封装属性值 MutablePropertyValues mpvs = null; Listoriginal; if (System.getSecurityManager() != null) { if (bw instanceof BeanWrapperImpl) { //设置安全上下文,JDK安全机制 ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } } 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; } //创建一个Bean定义属性值解析器,将Bean定义中的属性值解析为Bean实例对象的实际值 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(); //转换属性值,例如将引用转换为IOC容器中实例化对象引用 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); } }
这里主要是对需要转换的属性进行转换然后进行属性值的依赖注入。
至此属性的依赖注入分析结束,最后我们看下initializeBean方法是如何对bean进行初始化操作的,其源码如下:
//初始容器创建的Bean实例对象,为其添加BeanPostProcessor后置处理器 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //JDK的安全机制验证权限 if (System.getSecurityManager() != null) { //实现PrivilegedAction接口的匿名内部类 AccessController.doPrivileged((PrivilegedAction
至此,bean初始化操作的总体过程分析结束,当然中间存在一些细节方面的点没有分析清楚,还需要各位小伙伴自行研究,然后有什么问题可以留言,大家一起讨论一起进步。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/77024.html
摘要:初始化我们知道容器初始化后会对容器中非懒加载的,单例的以及非抽象的定义进行的初始化操作,所以我们分析源码的入口也就是在容器初始化的入口,分析容器初始化后在什么地方开始第一次的初始化。 前言 Spring IOC容器在初始化之后会对容器中非懒加载的,单例的以及非抽象的bean定义进行bean的初始化操作,同时会也涉及到Bean的后置处理器以及DI(依赖注入)等行为。对于Bean的初始化,...
摘要:前言以下源码基于版本解析。实现源码分析对于的实现,总结来说就是定位加载和注册。定位就是需要定位配置文件的位置,加载就是将配置文件加载进内存注册就是通过解析配置文件注册。下面我们从其中的一种使用的方式一步一步的分析的实现源码。 前言 以下源码基于Spring 5.0.2版本解析。 什么是IOC容器? 容器,顾名思义可以用来容纳一切事物。我们平常所说的Spring IOC容器就是一个可以容...
摘要:的在单例被破坏时由进行方法调用。定义并实现这两个接口容器创建完成注解是的缩写,意思是规范提案。在创建完成并且属性赋值完成来执行初始化方法在容器销毁之前回调通知支持自动装配,类似。 Spring注解应用篇--IOC容器Bean生命周期 这是Spring注解专题系类文章,本系类文章适合Spring入门者或者原理入门者,小编会在本系类文章下进行企业级应用实战讲解以及spring源码跟进。本文...
摘要:入门篇学习总结时间年月日星期三说明本文部分内容均来自慕课网。主要的功能是日志记录,性能统计,安全控制,事务处理,异常处理等等。 《Spring入门篇》学习总结 时间:2017年1月18日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:https://github.com/zccodere/s...个人学习源码:https://git...
阅读 808·2021-11-25 09:43
阅读 1672·2021-09-29 09:42
阅读 1892·2019-08-30 15:55
阅读 3413·2019-08-30 15:54
阅读 2617·2019-08-30 13:20
阅读 3500·2019-08-29 13:25
阅读 907·2019-08-28 18:03
阅读 1777·2019-08-26 13:44