Spring源码解析-PropertyEditor
来源:互联网 发布:mac队员被杀 编辑:程序博客网 时间:2024/05/17 21:56
PropertyEditor最早用于Swing编程中,在Spring中主要被用于xml内value的转换和mvc中参数值得转换。
Spring容器在applyPropertyValues通过TypeConverter对value进行值得转换,具体的调用栈如下
createBean->doCreateBean->populateBean->applyPropertyValues
具体的转换代码如下
private Object convertForProperty(Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {if (converter instanceof BeanWrapperImpl) {return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);}else {PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);return converter.convertIfNecessary(value, pd.getPropertyType(), methodParam);}}
从源码可以看出当customTypeConverter为空是,将会使用BeanWrapper进行转换,因为BeanWrapper实现了PropertyEditorRegistry接口。
现在讲讲如何配置自定义的PropertyEditor, 通过配置CustomEditorConfigurer代码如下
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="com.spring.User" value="com.spring.UserEditor"/> </map> </property></bean>CustomEditorConfigurer本质上是一个BeanFactoryPostProcessor, 所以在初始化容器之后,会通过ConfigurableListableBeanFactory的addPropertyEditorRegistrar和registerCustomEditor, 将其自身配置的propertyEditorRegistrars和customEditors添加到容器中。那么就到了下一步,如果使用这些最后都变成PropertyEditor并且用于转换value为对应类型的object。
首先要知道AbstractBeanFactory中有以下变量,
customEditors, propertyEditorRegistrars, typeConverter, conversionService
typeConverter内部结合了conversionService和PropertyEditor来转换值,
conversionService是spring3.0新加的用于转换的接口和PropertyEditor属于一个性质的东西。
之前说到BeanWrapper是一个实现了PropertyEditorRegistry的接口,其内部有很多的PropertyEditor,这些editor则是通过beanFactory的initBeanWrapper注册到beanwrapper当中的,代码如下:
/** * Initialize the given BeanWrapper with the custom editors registered * with this factory. To be called for BeanWrappers that will create * and populate bean instances. * <p>The default implementation delegates to {@link #registerCustomEditors}. * Can be overridden in subclasses. * @param bw the BeanWrapper to initialize */protected void initBeanWrapper(BeanWrapper bw) {bw.setConversionService(getConversionService());registerCustomEditors(bw);}
/** * Initialize the given PropertyEditorRegistry with the custom editors * that have been registered with this BeanFactory. * <p>To be called for BeanWrappers that will create and populate bean * instances, and for SimpleTypeConverter used for constructor argument * and factory method type conversion. * @param registry the PropertyEditorRegistry to initialize */protected void registerCustomEditors(PropertyEditorRegistry registry) {PropertyEditorRegistrySupport registrySupport =(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);if (registrySupport != null) {registrySupport.useConfigValueEditors();}if (!this.propertyEditorRegistrars.isEmpty()) {for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {try {registrar.registerCustomEditors(registry);}catch (BeanCreationException ex) {Throwable rootCause = ex.getMostSpecificCause();if (rootCause instanceof BeanCurrentlyInCreationException) {BeanCreationException bce = (BeanCreationException) rootCause;if (isCurrentlyInCreation(bce.getBeanName())) {if (logger.isDebugEnabled()) {logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +"] failed because it tried to obtain currently created bean '" +ex.getBeanName() + "': " + ex.getMessage());}onSuppressedException(ex);continue;}}throw ex;}}}if (!this.customEditors.isEmpty()) {for (Map.Entry<Class<?>, Class<? extends PropertyEditor>> entry : this.customEditors.entrySet()) {Class<?> requiredType = entry.getKey();Class<? extends PropertyEditor> editorClass = entry.getValue();registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass));}}}
所以每一个BeanWrapper相当于都从BeanFactory中获取PropertyEditor,最终用于值转换,
对于BeanFactory而言,则在AbstractApplicationContext的prepareBeanFactory中添加一个ResourceEditorRegistrar。代码如下
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}
- Spring源码解析-PropertyEditor
- spring propertyEditor 小总结
- spring 强大的PropertyEditor
- Spring的自定义PropertyEditor
- Spring之PropertyEditor
- Spring PropertyEditor分析
- 探秘Spring的PropertyEditor
- [java][spring]PropertyEditor
- Spring的FactoryBean与PropertyEditor
- spring配置自定义的PropertyEditor
- 属性编辑器PropertyEditor-->Spring IoC
- 《Pro Spring》学习笔记之PropertyEditor
- 学习spring必须java基础知识-PropertyEditor
- java 框架基础知识(3)----PropertyEditor-->Spring IoC
- Spring IOC 自定义属性编辑器PropertyEditor
- Spring PropertyEditor 相关类的模拟实现
- Spring源码解析
- spring源码解析
- Unbantu 编译ffmpeg Android版本库
- ubuntu下安装teamviewer
- CentOS7通过yum安装Mysql5.7+修改默认密码+远程登录
- 237. Delete Node in a Linked List的C++解法
- Scsi-target-utils Quickstart Guide
- Spring源码解析-PropertyEditor
- 使用EasyPermissions 来打造简单的android6.0动态权限
- Linq 和 Lambda 查询中按照多个值进行分组GroupBy
- vue.js浅度监听和深度监听
- 新浪微博OAuth认证和存储
- Android Studio显示行数
- Spring中property资源文件动态映射xml载入方法
- 第八章 VMware Workstation中Linux克隆步骤
- sonarqube安装使用