spring 自定义属性解析器

gsluofu / 2024-09-01 / 原文

自定义属性解析器

org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory

beanFactory.setBeanClassLoader(getClassLoader());
//设置EL表达式解析器(${})
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//设置默认的属性解析器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

PropertyEditorSupport属性编辑器

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
        <map>
               <entry key="cn.com.luofu.selfEditor.Address" value="cn.com.luofu.selfEditor.AddressPropertyEditor"></entry>
        </map>
    </property>
</bean>
//属性编辑器注入
org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors->invokeBeanFactoryPostProcessors->invokeBeanFactoryPostProcessors->postProcessBeanFactory{
    //beanfactory中customEditors的map中添加对应属性解析器
    ...this.customEditors.forEach(beanFactory::registerCustomEditor{
        ...this.customEditors.put(requiredType, propertyEditorClass)...
    })
}
//实例化bean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean{
    ...instanceWrapper = createBeanInstance{
        ...instantiateBean{
            //BeanWrapperImpl extends AbstractNestablePropertyAccessor extends AbstractPropertyAccessor extends TypeConverterSupport extends PropertyEditorRegistrySupport 看出 BeanWrapperImpl 继承 PropertyEditorRegistrySupport
            ...BeanWrapper bw = new BeanWrapperImpl
                initBeanWrapper(bw){
                registerCustomEditors(bw){
                    //这里registry为传进来的bw,this为beanfactory(上面自定义解析器已经添加到了工厂)
                    ...this.customEditors.forEach((requiredType, editorClass) ->
					registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass))){
                        //PropertyEditorRegistrySupport属性customEditors加了自定义属性解析器
                       ...this.customEditors.put(requiredType, propertyEditor)...
                    }
                }
            }...
        }...
    }...
}
//属性编辑器获取
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean{
    ...applyPropertyValues{
        //处理value为依赖bean包括循环依赖
        ...valueResolver.resolveValueIfNecessary...
        ...convertForProperty->convertForProperty->convertForProperty->convertIfNecessary->convertIfNecessary{
            ...PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor{
                //从之前放进去的PropertyEditorRegistrySupport#findCustomEditor
                ...getCustomEditor{
                    //取出对应的edit如AddressPropertyEditor
                    ...this.customEditors.get(requiredType)...
                }...
            }...
            //对应的edit属性解析器解析
            ...doConvertValue->doConvertTextValue->editor.setAsText
        }...
    }...
}

ConversionService属性编辑器

conversionService(ConversionServiceFactoryBean,含属性GenericConversionService)创建过程 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean->invokeInitMethods->afterPropertiesSet{ //添加默认的属性转换器,大部分是转为string this.conversionService = createConversionService(){ ...return new DefaultConversionService()... } //注册自定义converter(this.converters通过xml注入的) ConversionServiceFactory.registerConverters(this.converters, this.conversionService){ ...else if (converter instanceof Converter) { //ConverterRegistry中添加属性解释器 registry.addConverter{ //GenericConversionService属性converters中添加解析器 ...addConverter... }... } }

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#convertForProperty->convertForProperty...->convertIfNecessary..->canConvert->conversionService.convert //从GenericConversionService属性converters中获取解析器,自定义convert需要实现Converter接口。如:StudentConverter implements Converter<String,Student>

Spel 表达式

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues{
    //convertForProperty 上面两个解析器 在el处理之后在处理
    ...resolveValueIfNecessary{
        ...else if (value instanceof TypedStringValue) {
            ...evaluate{
                ...doEvaluate->evaluateBeanDefinitionString->evaluate{
                    //el 解析器解析
                    ...this.expressionParser.parseExpression{
                        ...parseTemplate{
                            ...parseExpressions{
                                ... //#{和} 解析#{person.hobit}
                                    String prefix = context.getExpressionPrefix();
		                            String suffix = context.getExpressionSuffix()...
                            }...
                        }...
                    }...
                    return expr.getValue(sec){
                        ...getValue->getValueInternalgetValueRef->getValueInternal->getValueInternal->readProperty->read->getObject->getBean(key) @1
                    }
                }...
            }...
        }
    }...
}
// @1 将person.hobit拆分person和hobit分别解析
org.springframework.beans.factory.config.BeanExpressionContext#getObject{
    //key: person,然后通过反射获取属性值org.springframework.expression.spel.support.ReflectivePropertyAccessor.OptimalPropertyAccessor#read->method.invoke(target)
    ...this.beanFactory.getBean(key)...
}

循环依赖

<bean name="person" class="cn.com.luofu.dto.Person">
    <property name="hobit" value="zzz"></property>
    <property name="film"  ref="film"></property>
</bean>

<bean name="film" class="cn.com.luofu.el.Film">
    <property name="name" value="lisi"></property>
    <property name="person"  ref="person"></property>
</bean>
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean{
... // Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName){
			...getSingleton(beanName, true){
				//依次从一二三级缓存获取singletonObjects、earlySingletonObjects、singletonFactories。此时bean还未标记singletonsCurrentlyInCreation(方法后面的getSingleton(beanName, () ->这个方法会标记)返回的为null.如果标记了接下来的代码会从二级缓存拿值放到二级缓存
			}...
				...getSingleton(beanName,()...){
					...beforeSingletonCreation{
						...this.singletonsCurrentlyInCreation.add(beanName)...
					}...
					...getObject{
						//lumbdar 
						...doCreateBean{
							//判读支持循环引用后(含标记singletonsCurrentlyInCreation为true)
							...addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)){
								//实例化后放到三级缓存
								...if (!this.singletonObjects.containsKey(beanName)) {
								this.singletonFactories.put(beanName, singletonFactory);
									this.earlySingletonObjects.remove(beanName);
									this.registeredSingletons.add(beanName);
								}...
							}...
						}...
					}...
					...afterSingletonCreation{
						...this.singletonsCurrentlyInCreation.remove(beanName)...
					}...
					...addSingleton{
						//实例化完成后放到一级缓存,从二级、三级缓存移除
						...this.singletonObjects.put(beanName, singletonObject);
							this.singletonFactories.remove(beanName);
							this.earlySingletonObjects.remove(beanName);
							this.registeredSingletons.add(beanName);...
					}...
				}...
		}...
}

getbean("person")->