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")->

相關文章