PropertyEditor及BeanInfo的基本用法

举个例子:GUI上有个下拉框里面有"特级","高级","中级","初级"这几个选项,当选中之后会处理一些事情。但具体的代码里一般不会设置为字符串类型,而是int或者枚举类型。如下:

public class LvBean {
	private int lv;//0 特级 1高级 2中级 3低级

	public int getLv() {
		return lv;
	}

	public void setLv(int lv) {
		this.lv = lv;
	}

}

这样的情况如果放在浏览器里则可以用<select><option>的name,value来表示即可,放到java代码里则肯定需要另外处理的,比如:

if (value == "特级"){
    
}else if...
...
...

因为这种情况的普遍性,所以实现接口是不错的,下面是一个接口方法:根据字符串返回真正的值。

T getFromAsText(String text) ;

我们可以写实现这个接口,然后在里面去判断,如下:

@Override
int getFromAsText(String text) {
    if (value == "特级"){
        return 0;
    }else if...
    ...
    ...
}

很不错!!!但前辈们远远比我们想的多。

他们早就这样做了,且做的更好。

这就是PropertyEditor。

从字面上来说,就是属性编辑器。

这是一个接口,它是属于java.beans包的。

这个接口创造的目的是为了GUI而创造的。但它也可以做其他的一些事情。

它最重要的是这几个方法:

void setValue(Object value);//设置值

Object getValue();//获得值

void setAsText(String text) throws java.lang.IllegalArgumentException;//根据字符串设置值

setAsText这个方法就是将字符串转换成其他值,根据自己需要去实现它,可以转成日期啊等等。

光有PropertyEditor接口的话还是比较懵逼的,毕竟是void方法,即使实现了该接口,那么set到哪里啊?

其他它有个基本实现类PropertyEditorSupport,算是一个强适配器吧。

里面的代码非常简单。

你会发现它里面维护了几个Object变量,所有的操作都是围绕着这几个变量来的,这下就清晰很多了。(当你读到这里的时候,请停下脚步查看PropertyEditorSupport源码)

实际上我们可以不去直接实现PropertyEditor的,而是直接继承自PropertyEditorSupport,根据上面的例子,修改setAsText,如下代码:

public class LvPropertyEdioter extends PropertyEditorSupport{
	private static String [] lvs = {"特级","高级","中级","初级"};
	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		for (int i = 0; i < lvs.length; i++) {
			if (lvs[i].equals(text)){
				setValue(i);
				break;
			}
		}
	}
}

这个会把传来的字符串比较,如果相同,把索引set到Object变量里。那么取的时候直接getValue的。

 

如果只是实现接口来处理这种转换工作的话,代码还不够优秀,我们可以更进一步。

我们设想一下,如果我们做了类似于这样JSON配置文件:

    [
    {	
		className:LvBean.class,
		fieldName:"lv",
		fieldEdioter:LvPropertyEdioter.class
    },{
        ...
    }
    ...
    ]
    

到时候直接反射操作该多爽啊?

 在持续开发的过程中,配置以及修改配置是很不如意的事情。

我们可以通过实例对象BeanInfo来这样做:

BeanInfo也是接口,这个接口就是指Bean的信息。包括什么类的什么属性,使用的什么PropertyEdioter。

它有个适配器:SimpleBeanInfo,我们直接继承它即可。

注意一件小事,听说实现BeanInfo的时候命名规则是要在Bean类后面加上BeanInfo这样的命名方式。如下:

public class LvBeanBeanInfo extends SimpleBeanInfo{
	@Override
	public PropertyDescriptor[] getPropertyDescriptors() {
		PropertyDescriptor pd = null;
		try {
			pd = new PropertyDescriptor("lv", LvBean.class);
			pd.setPropertyEditorClass(LvPropertyEdioter.class);
		} catch (IntrospectionException e) {
			e.printStackTrace();
		}
		return new PropertyDescriptor[]{pd};
	}
}

重写属性描述器方法。把Bean类,属性以及edioter类关联到一起。

来写个测试吧。

/**
 *  需求:面板选中“高级”,处理一些事物
 * @author dmw
 *
 * 2018年12月4日
 */
public class Test {
	
	
	public static void main(String[] args) throws Exception {
		String fieldName = "lv";//等级
		String fieldTextVal = "中级";//内容
		Class<LvBeanBeanInfo> clazz = LvBeanBeanInfo.class;//bean的配置信息对象
		
		choose(fieldName,fieldTextVal,clazz);
	}
	/**
	 * 选中
	 */
	private static void choose(String fieldName,String fieldTextVal,Class<? extends BeanInfo> clazz) throws Exception {
		
		PropertyEditor editor = getPropertyEditor(fieldName,clazz);
		if (editor == null){
			throw new NullPointerException();
		}
		//属性编辑器来转换字符串
		editor.setAsText(fieldTextVal);
		Object value = editor.getValue();
		//进一步处理
		handleLv(value);
	}
	
	/**
	 * 获取属性编辑器
	 * 
	 */
	private static PropertyEditor getPropertyEditor(String fieldName,Class<? extends BeanInfo> clazz) throws Exception {
		BeanInfo Info = clazz.newInstance();
		PropertyDescriptor[] descriptors = Info.getPropertyDescriptors();
		for (PropertyDescriptor propertyDescriptor : descriptors) {
			//如果里面有属性名相同的,那么就直接返回附带的属性编辑器对象
			if (propertyDescriptor.getName().equals(fieldName)){
				Class<? extends PropertyEditor> editorClass = (Class<? extends PropertyEditor>) propertyDescriptor.getPropertyEditorClass();
				return  editorClass.newInstance();
			}
		}
		return null;
	}
	/**
	 * 进一步处理
	 * @param value
	 */
	private static void handleLv(Object value) {
		System.out.println(value);
		//可以通过反射再赋值给LvBean
	}
	
}

 

运行还不错。

结语:

通过模块解耦的方式来转换字符串类型只是PropertyEditor的一个功能而已。

spring写了很多类来实现它,有将字符串转成int的,字符串转double的,字符串转class的等等等等。这些editor既可用于xml解析注入对象属性,又可以用于http接参数到Controller类的方法参数里面。(都是字符串转其他类型啊)

BeanInfo里面还有其他的一些方法,包括事件的处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值