spring5.1.x源码解析之四(自定义属性编辑器执行逻辑)

默认属性编辑器

这段代码的意思就设置默认属性编辑器

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	...
		//设置默认属性编辑器
		//registerBeanPostProcessors会注册所有自定义编辑器,对应AbstractBeanFactory.customEditors
		//AbstractBeanFactory.initBeanWrapper会使用编辑器,对应AbstractBeanFactory.propertyEditorRegistrars
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

...
	}

在初始化BeanWrapper的时候会注册属性编辑器到BeanWrapper中

/*
org.springframework.beans.factory.support.AbstractBeanFactory#initBeanWrapper
 */
	protected void initBeanWrapper(BeanWrapper bw) {
...
		//注册编辑器
		registerCustomEditors(bw);
	}
	protected void registerCustomEditors(PropertyEditorRegistry registry) {
...
					//批量注册通用属性编辑器
						if (registry instanceof PropertyEditorRegistrySupport) {
			((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
		}
...
		}
	}

执行到这里基本就注册到BeanWrapper中overriddenDefaultEditors属性了

	public void overrideDefaultEditor(Class<?> requiredType, PropertyEditor propertyEditor) {
		if (this.overriddenDefaultEditors == null) {
			this.overriddenDefaultEditors = new HashMap<>();
		}
		this.overriddenDefaultEditors.put(requiredType, propertyEditor);
	}

自定义属性编辑器方式一之直接注册

配置文件如下

    <bean id="userDate" class="org.example.custom.editor.UserDate">
        <property name="dataValue" value="2010-10-10"/>
    </bean>
 <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
           <property name="customEditors">
               <map>
                   <entry key="java.util.Date" value="org.example.custom.editor.DatePropertyEditor">
                   </entry>
               </map>
           </property>
       </bean>

自定义解析类

public class DatePropertyEditor extends PropertyEditorSupport {
    private String format = "yyyy-MM-dd";

    public void setFormat(String format) {
        this.format = format;
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        try {
            Date parse = simpleDateFormat.parse(text);
            this.setValue(parse);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

首先可以看到配置文件配置的CustomEditorConfigurer类继承了BeanFactoryPostProcessor接口,这个接口的意思就是生成bean之前首先执行这个接口里面postProcessBeanFactory方法

public class CustomEditorConfigurer implements BeanFactoryPostProcessor, Ordered {
@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		if (this.propertyEditorRegistrars != null) {
			for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars) {
				beanFactory.addPropertyEditorRegistrar(propertyEditorRegistrar);
			}
		}
...
	}
}

当执行invokeBeanFactoryPostProcessors方法的时候,会查询所有的继承了BeanFactoryPostProcessor接口的postProcessBeanFactory方法

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		...
				// Invoke factory processors registered as beans in the context.
				//激活各种BeanFactory处理器
				//BeanFactoryPostProcessor作用域容器级,仅仅对容器中的bean进行后置处理,如propertyPlaceholderConfig,继承order可实现排序调用功能
				//BeanFactoryPostProcessor可以修改实际的bean实例
				invokeBeanFactoryPostProcessors(beanFactory);***
	}

这个时候就会把配置文件配置了customEditors属性的值经过CustomEditorConfigurer类的postProcessBeanFactory方法,注册到BeanFactorycustomEditors属性,然后当执行registerCustomEditors的时候注册

	/*
	注册默认属性编辑器
	注册自定义属性编辑器
	 */
	protected void registerCustomEditors(PropertyEditorRegistry registry) {
...
		//注册自定义属性编辑器
		if (!this.customEditors.isEmpty()) {
			this.customEditors.forEach((requiredType, editorClass) ->
					registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
		}
	}

执行注册方法,注册到customEditors缓存中

	@Override
	public void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor) {
...
			//注册自定义属性编辑器
			if (this.customEditors == null) {
				this.customEditors = new LinkedHashMap<>(16);
			}
			this.customEditors.put(requiredType, propertyEditor);
			this.customEditorCache = null;
		...
	}

自定义属性编辑器方式二之本地注册

配置文件

    <!-- 注册自定义属性解析器2  初始化的时候,调用注入本地方法注册-->
        <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
            <property name="propertyEditorRegistrars">
                <list>
                    <bean class="org.example.custom.editor.DatePropertyEditorRegistry"></bean>
                </list>
            </property>
        </bean>

这里使用spring提供的解析器

public class DatePropertyEditorRegistry implements PropertyEditorRegistrar {

    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(Date.class,
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
    }
}

用的还是CustomEditorConfigurer,只不过注入的属性是propertyEditorRegistrars,跟上述一样,执行的方法变了.会加载到BeanFactorypropertyEditorRegistrars属性中

@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		//注册
		if (this.propertyEditorRegistrars != null) {
			for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars) {
				beanFactory.addPropertyEditorRegistrar(propertyEditorRegistrar);
			}
		}
..
	}

在初始化BeanWrapper的时候会执行以下方法

protected void registerCustomEditors(PropertyEditorRegistry registry) {
...
					//批量注册通用属性编辑器
					registrar.registerCustomEditors(registry);
...
	}

然后调用我们自定义的类进行注册

public class DatePropertyEditorRegistry implements PropertyEditorRegistrar {

    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(Date.class,
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
    }
}

执行注册方法,注册到customEditors缓存中

	@Override
	public void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor) {
...
			//注册自定义属性编辑器
			if (this.customEditors == null) {
				this.customEditors = new LinkedHashMap<>(16);
			}
			this.customEditors.put(requiredType, propertyEditor);
			this.customEditorCache = null;
	...	
	}

自定义属性编辑器方式三之自定义转换服务类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值