做试客需要去哪些网站,重庆网站建设023kw,长沙市网站制作哪家好,做盗版网站的目录 1.1 循环依赖1.2 属性填充1.2.1 populateBean方法1.2.2 initializeBean方法执行Aware方法执行BeanPostProcessor后置处理器的前置处理方法执行初始化方法执行BeanPostProcessor后置处理器的后置处理方法#xff1a;postProcessAfterInitialization()#xff0c;允许对be… 目录 1.1 循环依赖1.2 属性填充1.2.1 populateBean方法1.2.2 initializeBean方法执行Aware方法执行BeanPostProcessor后置处理器的前置处理方法执行初始化方法执行BeanPostProcessor后置处理器的后置处理方法postProcessAfterInitialization()允许对bean实例进行包装 1.3 根据 scope 注册 bean 官网Home参考书籍Spring源码深度解析-郝佳编著-微信读书
AbstractAutowireCapableBeanFactory 上一节我们详细的解释了Bean的实例化的后置处理我们接着往下看doCreateBean的方法依赖的处理
// 是否需要提前曝光用来解决循环依赖时使用boolean earlySingletonExposure (mbd.isSingleton() this.allowCircularReferences isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace(Eagerly caching bean beanName to allow for resolving potential circular references);}// 注释 5.2 将缓存中的 bean 信息更新解决循环依赖 第二个参数是回调接口实现的功能是将切面动态织入 beanaddSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));}依赖注入概念就是A在getBean初始化时如果依赖了另一个bean B那么会先去调用B的getBean初始化B。但是B再去getBean时又依赖A。那么就出现了死循环。Spring按照域Scope进行处理如果是非单利模式则抛出异常。
1.1 循环依赖
我们看到上面的代码虽然短短几行但是解决了循环依赖的问题我们新总体讲述一下大体步骤 虽然只有短短的几行代码但是这是单利模式循环依赖的实现。上面判断了三个条件 1、当前Bean为单例Scope 2、容器级别的allowCircularReferences是否允许循环依赖默认为true 3、当前Bean是否标记为正在创建中存放在singletonsCurrentlyInCreation容器中 如果允许提前暴露通过addSingletonFactory()方法将生成bean的工厂ObjectFactory添加到三级缓存(singletonFactories)中这是Spring解决循环依赖非常关键的代码。 DefaultSingletonBeanRegistry
protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) {Assert.notNull(singletonFactory, Singleton factory must not be null);// 加锁synchronized (this.singletonObjects) {// 1、如果一级缓存中不存在当前beanName的时候才能进if判断if (!this.singletonObjects.containsKey(beanName)) {// 2、将beanName ObjectFactory的映射关系添加到三级缓存中注意添加的是创建bean的对象工厂singletonFactorythis.singletonFactories.put(beanName, singletonFactory);// 3、从二级缓存中移除当前beanNamethis.earlySingletonObjects.remove(beanName);// 4、将beanName添加到已注册单例集合中this.registeredSingletons.add(beanName);}}
}其实是在DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)方法中使用到singletonObject singletonFactory.getObject()执行singletonFactory.getObject()的时候实际上就是执行getEarlyBeanReference()方法获取早期bean的对象引用。
我们先简单看看三级缓存代码部分后面单独文章详细介绍 DefaultSingletonBeanRegistry
// 一级缓存用于保存beanName和创建bean实例之间的关系beanName - bean instance
private final MapString, Object singletonObjects new ConcurrentHashMap(256);// 三级缓存用于保存beanName和创建bean的工厂之间的关系beanName - ObjectFactory
private final MapString, ObjectFactory? singletonFactories new HashMap(16);// 二级缓存用于保存beanName和创建bean实例之间的关系beanName - bean instance
// 与一级缓存的区别当一个单例bean被放在二级缓存中后当bean还在创建过程中就可以通过getBean方法获取到了目的是用来检测循环引用
private final MapString, Object earlySingletonObjects new ConcurrentHashMap(16);getEarlyBeanReference()获取早期访问指定 bean的引用
/*** 获取早期访问指定 bean 的引用通常用于解析循环引用* param beanName* param mbd* param bean* return*/protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject bean;// 1、如果bean 定义不是“合成的”并且工厂中存在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器才会进入下面的逻辑if (!mbd.isSynthetic() hasInstantiationAwareBeanPostProcessors()) {// 2、获取工厂中所有已注册的BeanPostProcessor后置增强器for (BeanPostProcessor bp : getBeanPostProcessors()) {// 3、判断是否属于SmartInstantiationAwareBeanPostProcessor类型if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {SmartInstantiationAwareBeanPostProcessor ibp (SmartInstantiationAwareBeanPostProcessor) bp;// 4、类型匹配的话则执行SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法获取bean的早期引用// getEarlyBeanReference()方法: 此回调使后处理器有机会尽早暴露包装器 - 即在目标 bean 实例完全初始化之前 默认实现是返回原始的bean对象exposedObject ibp.getEarlyBeanReference(exposedObject, beanName);}}}// 5、如果不存在SmartInstantiationAwareBeanPostProcessor则直接返回原始的bean对象return exposedObject;}
:::warning 注意上述代码中getEarlyBeanReference()方法并不是在这里就执行这里只是将【() - getEarlyBeanReference(beanName, mbd, bean)】这个函数式接口作为创建bean的对象工厂添加到三级缓存中而已后续解决循环依赖的时候就会从三级缓存中拿出这个对象工厂即执行ObjectFactory.getObject()方法的时候就会回调getEarlyBeanReference(beanName, mbd, bean)方法获取到提前暴露的bean的早期引用从而解决循环依赖。 :::
1.2 属性填充
经过上面的一些了过程终于来到实例化Bean // Initialize the bean instance.Object exposedObject bean;try {// 对 bean 进行填充将各个属性值注入// 如果存在对其它 bean 的依赖将会递归初始化依赖的 beanpopulateBean(beanName, mbd, instanceWrapper);// 调用初始化方法例如 init-methodexposedObject 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);}}首先我们来看看一个关键的方法populateBean
1.2.1 populateBean方法
AbstractAutowireCapableBeanFactory
protected void populateBean(String beanName, RootBeanDefinition mbd, Nullable BeanWrapper bw) {// 1、针对bean的包装器是否为空、是否存在为此 bean 定义的属性值做不同的处理if (bw null) {// 如果bean的包装器为空但是又存在为此 bean 定义的属性值Spring则会抛出BeanCreationException异常// 因为属性填充就是要给BeanWrapper 中的 bean 实例中的属性进行赋值的过程存在属性但是BeanWrapper为空也就是BeanWrapper 中的 bean 实例为空那么显然不行if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Cannot apply property values to null instance);} else {// 如果没有为此 bean 定义的属性值即没有可填充的属性则直接返回// 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.// InstantiationAwareBeanPostProcessor后置处理器可以在属性设置前修改bean// 2、如果bean定义不是合成的并且工厂中存在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器则需要处理执行它的postProcessAfterInstantiation()方法if (!mbd.isSynthetic() hasInstantiationAwareBeanPostProcessors()) {// 获取到bean工厂所有已经注册的BeanPostProcessorfor (BeanPostProcessor bp : getBeanPostProcessors()) {// 判断是否属于InstantiationAwareBeanPostProcessor类型if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp (InstantiationAwareBeanPostProcessor) bp;// 如果类型匹配的话将会执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法// postProcessAfterInstantiation()方法在bean实例化后属性填充之前被调用允许修改bean的属性默认实现是返回trueif (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {// 如果postProcessAfterInstantiation()方法返回false则跳过后面的属性填充过程return;}}}}// 3、获取到bean定义中封装好的属性值PropertyValues pvs (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);// 4、根据设置的自动注入方式名称或者类型获取属性bean递归getBean存入PropertyValues中int resolvedAutowireMode mbd.getResolvedAutowireMode();if (resolvedAutowireMode AUTOWIRE_BY_NAME || resolvedAutowireMode AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs new MutablePropertyValues(pvs);// 根据名称自动注入// Add property values based on autowire by name if applicable.if (resolvedAutowireMode AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}//根据类型自动注入// Add property values based on autowire by type if applicable.if (resolvedAutowireMode AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs newPvs;}// hasInstAwareBpps工厂是否存在将在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器boolean hasInstAwareBpps hasInstantiationAwareBeanPostProcessors();// needsDepCheck是否需要进行依赖检查boolean needsDepCheck (mbd.getDependencyCheck() ! AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds null;// 5、如果存在InstantiationAwareBeanPostProcessor后置处理器需要执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调if (hasInstAwareBpps) {if (pvs null) {pvs mbd.getPropertyValues();}// 执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调// postProcessProperties(): 允许对填充前的属性进行处理如对属性的验证// postProcessPropertyValues(): 对属性值进行修改通过基于原始的PropertyValues创建一个新的MutablePropertyValues实例添加或删除特定的值。// 不过目前方法已经被标记为过期在后续Spring版本中可能会被删除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;}}}// 6、执行依赖检查对应depend-on属性if (needsDepCheck) {if (filteredPds null) {filteredPds filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}// 依赖检查对应depend-on属性checkDependencies(beanName, mbd, filteredPds, pvs);}// 7、属性填充的具体过程即将属性值赋值到beanWrapper中bean实例的具体属性中if (pvs ! null) {// 开始填充属性值applyPropertyValues(beanName, mbd, bw, pvs);}
}我们来梳理一下他的流程
针对bean的包装器是否为空、是否存在为此 bean 定义的属性值做不同的处理。如果bean的包装器为空但是又存在为此 bean 定义的属性值Spring则会抛出BeanCreationException异常如果没有为此 bean 定义的属性值即没有可填充的属性则直接返回如果bean定义不是合成的并且工厂中存在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器则需要处理执行它的postProcessAfterInstantiation()方法获取到bean定义中封装好的属性值根据设置的自动注入方式名称或者类型获取属性bean递归getBean存入PropertyValues中如果存在InstantiationAwareBeanPostProcessor后置处理器需要执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调执行依赖检查对应depend-on属性属性填充的具体过程即将属性值赋值到beanWrapper中bean实例的具体属性中 1Bean包装器判断 // 1、针对bean的包装器是否为空、是否存在为此 bean 定义的属性值做不同的处理if (bw null) {// 如果bean的包装器为空但是又存在为此 bean 定义的属性值Spring则会抛出BeanCreationException异常// 因为属性填充就是要给BeanWrapper 中的 bean 实例中的属性进行赋值的过程存在属性但是BeanWrapper为空也就是BeanWrapper 中的 bean 实例为空那么显然不行if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Cannot apply property values to null instance);} else {// 如果没有为此 bean 定义的属性值即没有可填充的属性则直接返回// Skip property population phase for null instance.return;}}2调用**postProcessAfterInstantiation方法** if (!mbd.isSynthetic() hasInstantiationAwareBeanPostProcessors()) {// 获取到bean工厂所有已经注册的BeanPostProcessorfor (BeanPostProcessor bp : getBeanPostProcessors()) {// 判断是否属于InstantiationAwareBeanPostProcessor类型if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp (InstantiationAwareBeanPostProcessor) bp;// 如果类型匹配的话将会执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法// postProcessAfterInstantiation()方法在bean实例化后属性填充之前被调用允许修改bean的属性默认实现是返回trueif (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {// 如果postProcessAfterInstantiation()方法返回false则跳过后面的属性填充过程return;}}}}3封装值 // 3、获取到bean定义中封装好的属性值
PropertyValues pvs (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);4根据设置的自动注入方式名称或者类型获取属性bean递归getBean存入PropertyValues中重点理解 // 4、根据设置的自动注入方式名称或者类型获取属性bean递归getBean存入PropertyValues中int resolvedAutowireMode mbd.getResolvedAutowireMode();if (resolvedAutowireMode AUTOWIRE_BY_NAME || resolvedAutowireMode AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs new MutablePropertyValues(pvs);// 根据名称自动注入// Add property values based on autowire by name if applicable.if (resolvedAutowireMode AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}//根据类型自动注入// Add property values based on autowire by type if applicable.if (resolvedAutowireMode AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs newPvs;}// hasInstAwareBpps工厂是否存在将在创建时应用于单例 bean 的 InstantiationAwareBeanPostProcessor后置处理器boolean hasInstAwareBpps hasInstantiationAwareBeanPostProcessors();// needsDepCheck是否需要进行依赖检查boolean needsDepCheck (mbd.getDependencyCheck() ! AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);首先我们看看Spring提供了那几种注入方式 **AutowireCapableBeanFactor**y
int AUTOWIRE_NO 0;
// 名称
int AUTOWIRE_BY_NAME 1;
// 类型
int AUTOWIRE_BY_TYPE 2;
// 构造器
int AUTOWIRE_CONSTRUCTOR 3;
// 已废弃 自动
Deprecated
int AUTOWIRE_AUTODETECT 4;首先获取Bean的注入方式 AbstractBeanDefinition public int getResolvedAutowireMode() {// 自动注入if (this.autowireMode AUTOWIRE_AUTODETECT) {// Work out whether to apply setter autowiring or constructor autowiring.// If it has a no-arg constructor its deemed to be setter autowiring,// otherwise well try constructor autowiring.Constructor?[] constructors getBeanClass().getConstructors();for (Constructor? constructor : constructors) {// 构造器参数为0if (constructor.getParameterCount() 0) {// 类型注入return AUTOWIRE_BY_TYPE;}}// 构造器注入return AUTOWIRE_CONSTRUCTOR;}else {return this.autowireMode;}}我们首先来看看通过名称注入
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {// 1、获取需要注入的属性名称数组注意只获取不是“简单”属性类型基础类型、枚举、Number等的那些属性String[] propertyNames unsatisfiedNonSimpleProperties(mbd, bw);// 2、循环需要注入的属性根据名称自动注入for (String propertyName : propertyNames) {// 3、判断是否存在名称为propertyName的bean或者bean定义如果当前工厂中没找到还会递归所有的父工厂去查找if (containsBean(propertyName)) {// 4、通过getBean从工厂中获取到名称为propertyName的bean实例Object bean getBean(propertyName);// 5、将propertyName以及对应的属性值bean添加到MutablePropertyValues中pvs.add(propertyName, bean);// 6、注册依赖关系到两个缓存中dependentBeanMap、dependenciesForBeanMapregisterDependentBean(propertyName, beanName);if (logger.isTraceEnabled()) {logger.trace(Added autowiring by name from bean name beanName via property propertyName to bean named propertyName );}} else {// 7、如果工厂以及父工厂都没有找到名称为propertyName的bean或者bean定义则不处理这个属性if (logger.isTraceEnabled()) {logger.trace(Not autowiring property propertyName of bean beanName by name: no matching bean found);}}}}注册Bean的依赖关系 DefaultSingletonBeanRegistry
//为指定的Bean注入依赖的Bean
public void registerDependentBean(String beanName, String dependentBeanName) {// A quick check for an existing entry upfront, avoiding synchronization...//处理Bean名称将别名转换为规范的Bean名称String canonicalName canonicalName(beanName);SetString dependentBeans this.dependentBeanMap.get(canonicalName);if (dependentBeans ! null dependentBeans.contains(dependentBeanName)) {return;}// No entry yet - fully synchronized manipulation of the dependentBeans Set//多线程同步保证容器内数据的一致性//先从容器中bean名称--全部依赖Bean名称集合找查找给定名称Bean的依赖Beansynchronized (this.dependentBeanMap) {//获取给定名称Bean的所有依赖Bean名称dependentBeans this.dependentBeanMap.get(canonicalName);if (dependentBeans null) {//为Bean设置依赖Bean信息dependentBeans new LinkedHashSet(8);this.dependentBeanMap.put(canonicalName, dependentBeans);}//向容器中bean名称--全部依赖Bean名称集合添加Bean的依赖信息//即将Bean所依赖的Bean添加到容器的集合中dependentBeans.add(dependentBeanName);}//从容器中bean名称--指定名称Bean的依赖Bean集合找查找给定名称Bean的依赖Beansynchronized (this.dependenciesForBeanMap) {SetString dependenciesForBean this.dependenciesForBeanMap.get(dependentBeanName);if (dependenciesForBean null) {dependenciesForBean new LinkedHashSet(8);this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);}//向容器中bean名称--指定Bean的依赖Bean名称集合添加Bean的依赖信息//即将Bean所依赖的Bean添加到容器的集合中dependenciesForBean.add(canonicalName);}
}a、对Bean 的属性代调用getBean()方法完成依赖Bean 的初始化和依赖注入。 b、将依赖Bean 的属性引用设置到被依赖的Bean 属性上。 c、将依赖Bean 的名称和被依赖Bean 的名称存储在IOC 容器的集合中。 接下来看看通过类型注入
/*** 通过类型注入* param beanName* param mbd* param bw* param pvs*/protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {// 1、判断是否存在自定义的TypeConverter存在则使用自定义的否则还是使用入参指定的bwTypeConverter converter getCustomTypeConverter();if (converter null) {converter bw;}SetString autowiredBeanNames new LinkedHashSet(4);// 2、获取需要注入的属性名称数组注意只获取不是“简单”属性类型基础类型、枚举、Number等的那些属性String[] propertyNames unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {try {// 3、获取包装对象的特定属性的属性描述符PropertyDescriptor pd bw.getPropertyDescriptor(propertyName);// Dont try autowiring by type for type Object: never makes sense,// even if it technically is a unsatisfied, non-simple property.if (Object.class ! pd.getPropertyType()) {// 4、为指定属性的写入方法获取一个新的 MethodParameter 对象通常指的是获取setter方法MethodParameter methodParam BeanUtils.getWriteMethodParameter(pd);// Do not allow eager init for type matching in case of a prioritized post-processor.boolean eager !(bw.getWrappedInstance() instanceof PriorityOrdered);DependencyDescriptor desc new AutowireByTypeDependencyDescriptor(methodParam, eager);// 5、解析当前属性所匹配的bean实例并把解析到的bean实例的beanName存入autowiredBeanNamesObject autowiredArgument resolveDependency(desc, beanName, autowiredBeanNames, converter);if (autowiredArgument ! null) {// 6、如果解析到的bean实例不为空的话将propertyName以及对应的属性值autowiredArgument添加到MutablePropertyValues中pvs.add(propertyName, autowiredArgument);}for (String autowiredBeanName : autowiredBeanNames) {// 7、注册依赖关系到两个缓存中dependentBeanMap、dependenciesForBeanMap这里是beanName依赖了autowiredBeanNameregisterDependentBean(autowiredBeanName, beanName);if (logger.isTraceEnabled()) {logger.trace(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);}}}5如果存在InstantiationAwareBeanPostProcessor后置处理器需要执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调 // 5、如果存在InstantiationAwareBeanPostProcessor后置处理器需要执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调if (hasInstAwareBpps) {if (pvs null) {pvs mbd.getPropertyValues();}// 执行InstantiationAwareBeanPostProcessor的postProcessProperties()以及postProcessPropertyValues()方法回调// postProcessProperties(): 允许对填充前的属性进行处理如对属性的验证// postProcessPropertyValues(): 对属性值进行修改通过基于原始的PropertyValues创建一个新的MutablePropertyValues实例添加或删除特定的值。// 不过目前方法已经被标记为过期在后续Spring版本中可能会被删除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;}}}6依赖检查 // 6、执行依赖检查对应depend-on属性if (needsDepCheck) {if (filteredPds null) {filteredPds filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}// 依赖检查对应depend-on属性checkDependencies(beanName, mbd, filteredPds, pvs);}spring默认情况下是不检查依赖的如果要使用依赖检查需要手动的在配置文件中设置。 依赖检查有四种模式simple,objects,all,none AbstractAutowireCapableBeanFactory
protected void checkDependencies(String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, Nullable PropertyValues pvs)throws UnsatisfiedDependencyException {// 获取检查依赖模式int dependencyCheck mbd.getDependencyCheck();// 循环判断for (PropertyDescriptor pd : pds) {if (pd.getWriteMethod() ! null (pvs null || !pvs.contains(pd.getName()))) {boolean isSimple BeanUtils.isSimpleProperty(pd.getPropertyType());boolean unsatisfied (dependencyCheck AbstractBeanDefinition.DEPENDENCY_CHECK_ALL) ||(isSimple dependencyCheck AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||(!isSimple dependencyCheck AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS);if (unsatisfied) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),Set this property value or disable dependency checking for this bean.);}}}}7具体的属性填充 // 7、属性填充的具体过程即将属性值赋值到beanWrapper中bean实例的具体属性中if (pvs ! null) {// 开始填充属性值applyPropertyValues(beanName, mbd, bw, pvs);}/*** Apply the given property values, resolving any runtime references* to other beans in this bean factory. Must use deep copy, so we* dont permanently modify this property.* p应用给定的属性值解决任何在这个bean工厂运行时其他bean的引用。必须使用深拷贝所以我们* 不会永久地修改这个属性/p* param beanName the bean name passed for better exception information* -- 传递bean名以获得更好的异常信息* param mbd the merged bean definition* -- 合并后的bean定义* param bw the BeanWrapper wrapping the target object* -- 包装目标对象的BeanWrapper* param pvs the new property values* -- 新得属性值*/protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {//如果pvs没有PropertyValueif (pvs.isEmpty()) {//直接结束方法return;}//如果有安全管理器 且 bw是BeanWrapperImpld恶实例if (System.getSecurityManager() ! null bw instanceof BeanWrapperImpl) {//设置bw的安全上下文为工厂的访问控制上下文((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());}//MutablePropertyValuesPropertyValues接口的默认实现。允许对属性进行简单操作并提供构造函数来支持从映射 进行深度复制和构造MutablePropertyValues mpvs null;//原始属性值列表ListPropertyValue original;//如果pvs是MutablePropertyValues实例if (pvs instanceof MutablePropertyValues) {//将pvs强转为MutablePropertyValue实例mpvs (MutablePropertyValues) pvs;//isConverted:返回该holder是否只包含转换后的值(true),或者是否仍然需要转换这些值//如果mpvs只包含转换后的值if (mpvs.isConverted()) {// Shortcut: use the pre-converted values as-is.// 快捷方式使用 pre-conveted初始值try {//使用mpvs批量设置bw包装的Bean对象属性bw.setPropertyValues(mpvs);//终止方法。return;}catch (BeansException ex) {//捕捉Bean异常重新抛出Bean创佳异常错误设置属性值。throw new BeanCreationException(mbd.getResourceDescription(), beanName, Error setting property values, ex);}}//获取mpvs的PropertyValue对象列表original mpvs.getPropertyValueList();}else {//获取pvs的PropertyValue对象数组并将其转换成列表original Arrays.asList(pvs.getPropertyValues());}//获取工厂的自定义类型转换器TypeConverter converter getCustomTypeConverter();//如果工厂中没有设置自定义类型转换器if (converter null) {//使用bw作为转换器converter bw;}//BeanDefinitionValueResolver:在bean工厂实现中使用Helper类它将beanDefinition对象中包含的值解析为应用于 目标bean实例的实际值BeanDefinitionValueResolver valueResolver new BeanDefinitionValueResolver(this, beanName, mbd, converter);// Create a deep copy, resolving any references for values.// 创建一个深拷贝解析任何值引用ListPropertyValue deepCopy new ArrayList(original.size());//是否还需要解析标记boolean resolveNecessary false;//遍历orgininalfor (PropertyValue pv : original) {//如果pv已经是转换后的值if (pv.isConverted()) {//将pv添加到deepCopy中deepCopy.add(pv);}else {//pv需要转换值//获取pv的属性名String propertyName pv.getName();//获取pv的原始属性值Object originalValue pv.getValue();//AutowiredPropertyMarker.INSTANCE自动生成标记的规范实例if (originalValue AutowiredPropertyMarker.INSTANCE) {//获取propertyName在bw中的setter方法Method writeMethod bw.getPropertyDescriptor(propertyName).getWriteMethod();//如果setter方法为nullif (writeMethod null) {//抛出非法参数异常自动装配标记属性没有写方法。throw new IllegalArgumentException(Autowire marker for property without write method: pv);}//将writerMethod封装到DependencyDescriptor对象originalValue new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);}//交由valueResolver根据pv解析出originalValue所封装的对象Object resolvedValue valueResolver.resolveValueIfNecessary(pv, originalValue);//默认转换后的值是刚解析出来的值Object convertedValue resolvedValue;//可转换标记: propertyName是否bw中的可写属性 prepertyName不是表示索引属性或嵌套属性如果propertyName中有.||[就认为是索引属性或嵌套属性boolean convertible bw.isWritableProperty(propertyName) !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);//如果可转换if (convertible) {//将resolvedValue转换为指定的目标属性对象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.// 可以将转换后的值存储合并后BeanDefinition中以避免对每个创建的Bean实例进行重新转换//如果resolvedValue与originalValue是同一个对象if (resolvedValue originalValue) {//如果可转换if (convertible) {//将convertedValue设置到pv中pv.setConvertedValue(convertedValue);}//将pv添加到deepCopy中deepCopy.add(pv);}//TypedStringValue:类型字符串的Holder,这个holder将只存储字符串值和目标类型。实际得转换将由Bean工厂执行//如果可转换 originalValue是TypedStringValue的实例 orginalValue不是标记为动态【即不是一个表达式】// convertedValue不是Collection对象 或 数组else if (convertible originalValue instanceof TypedStringValue !((TypedStringValue) originalValue).isDynamic() !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {//将convertedValue设置到pv中pv.setConvertedValue(convertedValue);//将pv添加到deepCopy中deepCopy.add(pv);}else {//标记还需要解析resolveNecessary true;//根据pv,convertedValue构建PropertyValue对象并添加到deepCopy中deepCopy.add(new PropertyValue(pv, convertedValue));}}}//mpvs不为null 已经不需要解析if (mpvs ! null !resolveNecessary) {//将此holder标记为只包含转换后的值mpvs.setConverted();}// Set our (possibly massaged) deep copy.// 设置我们的深层拷贝(可能时按摩过的)try {//按原样使用deepCopy构造一个新的MutablePropertyValues对象然后设置到bw中以对bw的属性值更新bw.setPropertyValues(new MutablePropertyValues(deepCopy));}catch (BeansException ex) {//捕捉更新属性值的Bean异常//重新抛出Bean创建异常错误设置属性值throw new BeanCreationException(mbd.getResourceDescription(), beanName, Error setting property values, ex);}}
大体步骤
首先检查是否存在要应用的属性值如果属性值为空直接返回。如果有安全管理器且bw是BeanWrapperImpl的实例设置bw的安全上下文为工厂的访问控制上下文。创建MutablePropertyValues对象并根据传入的属性值对象pvs初始化。进行属性值的解析和类型转换确保属性值可以正确地应用到Bean实例中。最后将转换后的属性值设置到bw包装的Bean对象中更新Bean的属性值。
后面会出文章详细介绍的到这我们就完成了属性填充
1.2.2 initializeBean方法
initializeBean()主要完成如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等工作。 AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, Nullable RootBeanDefinition mbd) {// 注释 4.12 securityManage 是啥不确定-if (System.getSecurityManager() ! null) {AccessController.doPrivileged((PrivilegedActionObject) () - {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// 如果没有 securityManage方法里面校验了 bean 的类型需要引用 Aware 接口// 对特殊的 bean 处理Aware/ BeanClassLoader / BeanFactoryAwareinvokeAwareMethods(beanName, bean);}Object wrappedBean bean;if (mbd null || !mbd.isSynthetic()) {// 熟悉么后处理器又来了// 注释 7.3 bean 实例化阶段调用已经注册好的 beanPostProcessor 的 postProcessBeforeInitialization 方法wrappedBean applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 激活用户自定义的 init-method 方法invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd ! null ? mbd.getResourceDescription() : null),beanName, Invocation of init method failed, ex);}if (mbd null || !mbd.isSynthetic()) {// bean 实例化阶段调用已经注册好的 beanPostProcessor 的 postProcessAfterInitialization 方法wrappedBean applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}initializeBean()方法处理过程 1、执行Aware方法如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 2、执行BeanPostProcessor后置处理器的前置处理方法postProcessBeforeInitialization()允许对bean实例进行包装 3、执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method 4、执行BeanPostProcessor后置处理器的后置处理方法postProcessAfterInitialization()允许对bean实例进行包装
执行Aware方法
AbstractAutowireCapableBeanFactory
// 注释 4.12 securityManage 是啥不确定-if (System.getSecurityManager() ! null) {AccessController.doPrivileged((PrivilegedActionObject) () - {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// 如果没有 securityManage方法里面校验了 bean 的类型需要引用 Aware 接口// 对特殊的 bean 处理Aware/ BeanClassLoader / BeanFactoryAwareinvokeAwareMethods(beanName, bean);}invokeAwareMethods()执行Aware方法如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
// 实现Aware接口的bean在被初始化后可以取得一些相对应的资源如BeanFactory、ApplicationContext等下面就是具体的赋值过程
private void invokeAwareMethods(String beanName, Object bean) {if (bean instanceof Aware) {// 1、如果bean实现了BeanNameAware接口那么在bean内部可以获取到BeanName属性if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}// 2、如果bean实现了BeanClassLoaderAware接口那么在bean内部可以获取到BeanClassLoader对象if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl getBeanClassLoader();if (bcl ! null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}// 3、如果bean实现了BeanFactoryAware接口那么在bean内部可以获取到BeanFactory工厂对象if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}
}执行BeanPostProcessor后置处理器的前置处理方法
这里需要看一下上一篇的Bean的后置处理
Object wrappedBean bean;if (mbd null || !mbd.isSynthetic()) {// 2、执行BeanPostProcessor后置处理器的前置处理方法postProcessBeforeInitialization()允许对bean实例进行包装wrappedBean applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}applyBeanPostProcessorsBeforeInitialization()执行BeanPostProcessor后置处理器的前置处理方法 Overridepublic Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result existingBean;// 1、获取到当前工厂中注册的所有BeanPostProcessor后置处理器for (BeanPostProcessor processor : getBeanPostProcessors()) {// 2、执行每一个BeanPostProcessor的前置增强方法postProcessBeforeInitialization()Object current processor.postProcessBeforeInitialization(result, beanName);if (current null) {// 3、如果postProcessBeforeInitialization()返回为空则直接返回将不会执行后续的BeanPostProcessor后置处理器的增强return result;}// 4、使用增强后的bean current赋值给result然后返回result current;}return result;}执行初始化方法
try {// 3、执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-methodinvokeInitMethods(beanName, wrappedBean, mbd);} catch (Throwable ex) {throw new BeanCreationException((mbd ! null ? mbd.getResourceDescription() : null),beanName, Invocation of init method failed, ex);}invokeInitMethods()执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method
protected void invokeInitMethods(String beanName, Object bean, Nullable RootBeanDefinition mbd)throws Throwable {// 1、检查bean是否实现了InitializingBean接口如果实现了则需要执行InitializingBean接口的afterPropertiesSet()方法boolean isInitializingBean (bean instanceof InitializingBean);if (isInitializingBean (mbd null || !mbd.isExternallyManagedInitMethod(afterPropertiesSet))) {if (logger.isTraceEnabled()) {logger.trace(Invoking afterPropertiesSet() on bean with name beanName );}// 2、调用InitializingBean接口的afterPropertiesSet()方法if (System.getSecurityManager() ! null) {try {AccessController.doPrivileged((PrivilegedExceptionActionObject) () - {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());} catch (PrivilegedActionException pae) {throw pae.getException();}} else {((InitializingBean) bean).afterPropertiesSet();}}// 3、调用用户自定义的初始化方法比如init-method等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);}}
}执行BeanPostProcessor后置处理器的后置处理方法postProcessAfterInitialization()允许对bean实例进行包装
if (mbd null || !mbd.isSynthetic()) {// 4、执行BeanPostProcessor后置处理器的后置处理方法postProcessAfterInitialization()允许对bean实例进行包装wrappedBean applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}applyBeanPostProcessorsAfterInitialization()执行BeanPostProcessor后置处理器的后置处理方法postProcessAfterInitialization()允许对bean实例进行包装 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result existingBean;// 1、获取到工厂中注册的所有BeanPostProcessor后置增强器for (BeanPostProcessor processor : getBeanPostProcessors()) {// 2、执行BeanPostProcessor的后置增强方法postProcessAfterInitialization()Object current processor.postProcessAfterInitialization(result, beanName);if (current null) {// 3、如果postProcessAfterInitialization()返回为空则直接返回将不会执行后续的BeanPostProcessor后置处理器的增强return result;}// 4、使用增强后的bean current赋值给result然后返回result current;}return result;}1.3 根据 scope 注册 bean
注册DisposableBean的实现在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理。
// Register bean as disposable.// 根据 scope 注册 beantry {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, Invalid destruction signature, ex);}
AbstractBeanFactory protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc (System.getSecurityManager() ! null ? getAccessControlContext() : null);// 如果bean的作用域不是prototype且bean需要在关闭时进行销毁if (!mbd.isPrototype() requiresDestruction(bean, mbd)) {// 如果bean的作用域是singleton则会注册用于销毁的bean到disposableBeans缓存执行给定bean的所有销毁工作if (mbd.isSingleton()) {// Register a DisposableBean implementation that performs all destruction// work for the given bean: DestructionAwareBeanPostProcessors,// DisposableBean interface, custom destroy method.registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));} else {// 如果bean的作用域不是prototype、也不是singleton而是其他作自定义用域的话则注册一个回调以在销毁作用域内的指定对象时执行// A bean with a custom scope...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 registerDisposableBean(String beanName, DisposableBean bean) {// 注册用于销毁的bean到disposableBeans缓存synchronized (this.disposableBeans) {// private final MapString, Object disposableBeans new LinkedHashMap();this.disposableBeans.put(beanName, bean);}
}我们后面来详细分析到这我们就完成了Bean的整个流程后面我们正对各个模块来进行分析前面的分析这是一个整体流程的概述相当于下面的代码部分这只是正对下面的一个流程的分析
package org.springframework.shu;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
/*** description: 测试Bean* author: shu* createDate: 2023/4/3 14:56* version: 1.0*/
public class AppTest {Testpublic void MyTestBeanTest() {BeanFactory bf new XmlBeanFactory( new ClassPathResource(spring-config.xml));MyTestBean myTestBean (MyTestBean) bf.getBean(myTestBean);System.out.println(myTestBean.getName());}
}