小明学Spring基础系列——Bean封装之BeanWrapper

1. 前言

Spring里面有一个类名字叫BeanWrapper,在Spring创建bean对象的流程中频繁出现,所以我一直比较好奇这个类的作用,今天刚好有时间,就阅读源码分析一下。从字面意思理解,Spring的BeanWrapper是对Spring Bean进行封装打包的类,Spring在对Bean封装打包得到BeanWrapper对象之后,我们就可以通过BeanWrapper访问Bean的属性和方法(可以参考JAVABean内省的一些概念)。在Spring需要反射获取(设置)Bean的字段或者方法时(比如@Autowired注入字段时),就可以直接通过BeanWrapper获取。BeanWrapper的功能示例如下图所示。
在这里插入图片描述

2. BeanWrapper类型转换服务

BeanWrapper接口的继承体系如下,可以看到BeanWrapper比较关键的内容包含属性编辑管理、类型转换等。先简单介绍以下及格关键接口,下文会一一详细介绍这些概念。

  1. 属性编辑器PropertyEditor,有了它,你可以用String给一个Bean非字符串类型属性设置值(当然只支持几种内置的类型),如String转int等。
  2. 类型转换服务ConversionService,由于属性编辑器只支持把String转成其它类型,有一定的局限性(无法把非String的实例转为其它类型),String新建了ConversionService,有了它只要你提前写好转换逻辑,你可以把任何类型的实例设置给Bean的属性。
  3. 类型转换逻辑TypeConverter,既有PropertyEditor可以进行转换,又有ConversionService可以进行转换,Spring应该怎样统筹协调二者呢?这就是TypeConvert了

在这里插入图片描述

2.1 属性编辑器之PropertyEditor

属性编辑器并不是Spring框架中定义的接口,而是在JAVABean中定义的接口,属性编辑器有一个很重要的功能:把字符串转为特定类型的值,比如我们在Idea中调试程序的时候,可以在调试窗口输入字符串设置int字段的值,idea会把这个String转int类型然后设置到对应的字段,再比如在Spring配置文件里,我们往往通过字面值为Bean各种类型的属性提供设置值:不管是double类型还是int类型,在配置文件中都对应字符串类型的字面值。BeanWrapper就是通过属性编辑器设置Bean属性?属性编辑器的接口定义如下,对于非jwtBean,比较重要的方法是setAsTextgetAsText,用于把Spring转属性或者把属性转成字符串。有了PropertyEditor,我们就可以用字符串设置某个字段的值。

public interface PropertyEditor {
   

    void setValue(Object value);
    Object getValue();
    boolean isPaintable();
    void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box);
    String getJavaInitializationString();
    String getAsText();
    void setAsText(String text) throws java.lang.IllegalArgumentException;
    String[] getTags();
    java.awt.Component getCustomEditor();
    boolean supportsCustomEditor();
    void addPropertyChangeListener(PropertyChangeListener listener);
    void removePropertyChangeListener(PropertyChangeListener listener);

}

Spring默认实现了几十种PropertyEditor(重写了setAsTextgetAsText),包含集合、数组等常见类型的数据转换,BeanWrapper已经内置了这些属性编辑器,内置部分属性编辑器的集合如下所示(在PropertyEditorRegistrySupport类中):

	/**
	 * Actually register the default editors for this registry instance.
	 */
	private void createDefaultEditors() {
   
		this.defaultEditors = new HashMap<>(64);

		// Simple editors, without parameterization capabilities.
		// The JDK does not contain a default editor for any of these target types.
		this.defaultEditors.put(Charset.class, new CharsetEditor());
		this.defaultEditors.put(Class.class, new ClassEditor());
		this.defaultEditors.put(Class[].class, new ClassArrayEditor());
		this.defaultEditors.put(Currency.class, new CurrencyEditor());
		this.defaultEditors.put(File.class, new FileEditor());
		this.defaultEditors.put(InputStream.class, new InputStreamEditor());
		if (!shouldIgnoreXml) {
   
			this.defaultEditors.put(InputSource.class, new InputSourceEditor());
		}
		this.defaultEditors.put(Locale.class, new LocaleEditor());
		this.defaultEditors.put(Path.class, new PathEditor());
		this.defaultEditors.put(Pattern.class, new PatternEditor());
		this.defaultEditors.put(Properties.class, new PropertiesEditor());
		this.defaultEditors.
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-御狐神-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值