首页 > 其他分享 >spring 自定义属性解析器

spring 自定义属性解析器

时间:2024-09-01 15:36:40浏览次数:3  
标签:解析器 ... 自定义 spring beanName springframework org 属性

自定义属性解析器

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

标签:解析器,...,自定义,spring,beanName,springframework,org,属性
From: https://www.cnblogs.com/leifonlyone/p/18391335

相关文章

  • springboot+vue酒店后台管理系统【程序+论文+开题】计算机毕业设计
    系统程序文件列表开题报告内容研究背景随着旅游业的蓬勃发展和消费者需求的日益多元化,酒店行业面临着前所未有的挑战与机遇。传统的手工管理模式已难以满足现代酒店高效运营、精准服务及快速响应市场需求的要求。特别是在客户信息管理、员工调度、客房资源配置及预订流程等......
  • springboot+vue家政服务管理系统【程序+论文+开题】计算机毕业设计
    系统程序文件列表开题报告内容研究背景随着现代生活节奏的加快,家庭对于高效、便捷的家政服务需求日益增长。传统家政服务行业中,信息不对称、服务质量参差不齐、预约流程繁琐等问题日益凸显,难以满足现代家庭对品质生活的追求。在此背景下,开发一套集智能化、信息化于一体的家......
  • springboot+vue家具销售平台【程序+论文+开题】计算机毕业设计
    系统程序文件列表开题报告内容研究背景随着互联网的飞速发展,电子商务已成为推动全球经济增长的重要力量。在家居消费领域,消费者对于家具的购买需求日益多元化和个性化,传统的线下销售模式已难以满足消费者对于便捷性、丰富性及性价比的追求。家具销售平台作为电子商务的重要......
  • 基于springboot+vue.js的经济新闻资讯附带文章源码部署视频讲解等
    文章目录前言详细视频演示具体实现截图核心技术介绍后端框架SpringBoot前端框架Vue持久层框架MyBaits为什么选择我代码参考数据库参考测试用例参考源码获取前言......
  • 基于SpringBoot+Vue的时尚美妆电商网站设计与实现(2024年最新,原创项目)
    文章目录1.前言2.详细视频演示3.论文参考4.项目运行截图5.技术框架5.1后端采用SpringBoot框架5.2前端框架Vue6.可行性分析7.系统测试7.1系统测试的目的7.2系统功能测试8.数据库表设计9.代码参考10.数据库脚本11.作者推荐项目12.为什么选择我?13.获取源......
  • 基于SpringBoot+Vue的毕业生就业推荐系统(2024最新,原创项目)
    文章目录1.前言2.详细视频演示3.论文参考4.项目运行截图5.技术框架5.1后端采用SpringBoot框架5.2前端框架Vue6.可行性分析7.系统测试7.1系统测试的目的7.2系统功能测试8.数据库表设计9.代码参考10.数据库脚本11.作者推荐项目12.为什么选择我?13.获取源......
  • 基于Java+SpringBoot+Mysql在线众筹系统功能设计与实现一
    一、前言介绍:1.1项目摘要随着互联网的普及和人们消费观念的转变,众筹作为一种创新的融资方式,逐渐受到社会各界的关注和青睐。它打破了传统融资模式的限制,为初创企业、艺术家、公益项目等提供了更为灵活和便捷的融资渠道。因此,开发众筹系统旨在满足这一市场需求,促进创新项......
  • 毕业设计-基于Springboot+Vue的大学生租房系统的设计与实现(源码+LW+包运行)
    源码获取:https://download.csdn.net/download/u011832806/89456841基于SpringBoot+Vue的大学生租房系统开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven系统演示视频:链接:https://pan.baidu.com/s/1oXxVE3PeuLS5YOJvYjvKKw?pwd=......
  • spring学习日记-day5-代理模式
    一、学习目标        代理模式是一种常用的设计模式,它主要用于在不修改原有对象代码的情况下,通过引入一个代理对象来控制对原有对象的访问,从而增强原有对象的功能。代理模式主要分为两种:静态代理和动态代理。尽管Spring框架本身更多地利用了动态代理来实现其功能,但理......
  • springboot+vue+mybatis计算机毕业设计飞机订票系统+PPT+论文+讲解+售后
    快速发展的社会中,人们的生活水平都在提高,生活节奏也在逐渐加快。为了节省时间和提高工作效率,越来越多的人选择利用互联网进行线上打理各种事务,然后线上管理系统也就相继涌现。与此同时,人们开始接受方便的生活方式。他们不仅希望页面简单大方,还希望操作方便,可以快速锁定他们需......