基于JavaBean编辑器读取peroperties文件的实例
引言
最近在重读《精通Spring+4.x++企业应用开发实战》这本书,看到了有关JavaBean编辑器的部分,了解到PropertyEditor和BeanInfo的使用。不得不说,BeanInfo是一个很强大的东西,Java中的内省也与之有一点点小关联。
JavaBean、PropertyEditor与BeanInfo
JavaBean简单介绍
JavaBean是一种Java写成的可重用组件,本质上还是一个Java类,但是与一般的Java类不同,JavaBean必须有一个无参的构造函数,其字段必须私有化,并提供set、get方法供外界使用。根据书中所介绍,Sun所制定的JavaBean规范很大程度山是为了IDE准备的--它让IDE能够以可视化的方式设置JavaBean的属性。
PropertyEditor接口
PropertyEditor是属性编辑器的接口,其作用是将一个String类型的值转换为JavaBean的属性。Java为PropertyEditor提供了一个默认的实现类PropertyEditorSupport。
BeanInfo接口
BeanInfo用于描述JavaBean哪些属性可以编辑及对应属性编辑器。Java为BeanInfo也提供了一个默认实现--SimpleBeanInfo。
其他
更多有关JavaBean以及这两个接口的知识,可以购买这本书《精通Spring+4.x++企业应用开发实战》,或者看我的Copy
一个小例子
在《精通Spring+4.x++企业应用开发实战》中使用的例子是根据《CoreJavaII》的一个例子改变而成,但是有一个小缺点,该例子使用到了Swing,演示时需要将代码打成JAR包,使用IDE组件扩展管理功能注册到IDE中,不太方便,因此我特意尝试用JavaBean编辑器读取properties文件作为一个小例子。
定义一个JavaBean
我们先定义一个Person类,用作JavaBean
/**
*一个简单的JavaBean
*@authoraming
*
*/
publicclassPersonimplementsSerializable{
privatestaticfinallongserialVersionUID=6366021085463785872L;
/**
*姓名
*/
privateStringname;
/**
*年龄
*/
privateintage;
/**
*性别
*/
privateGendergender;
/**
*生日
*/
privateDatebirthday;
/**
*是否结婚
*/
privatebooleanmarried;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
publicGendergetGender(){
returngender;
}
publicvoidsetGender(Gendergender){
this.gender=gender;
}
publicDategetBirthday(){
returnbirthday;
}
publicvoidsetBirthday(Datebirthday){
this.birthday=birthday;
}
publicbooleanisMarried(){
returnmarried;
}
publicvoidsetMarried(booleanmarried){
this.married=married;
}
publicPerson(){
super();
}
@Override
publicStringtoString(){
return"Person[name="+name+",age="+age+",gender="+gender+",birthday="+birthday+",married="
+married+"]";
}
}
其中Gender是我自定义的枚举,其代码如下:
/**
*表示性别的枚举类
*@authoraming
*
*/
publicenumGender{
M(1,"男"),F(2,"女");
privateintid;
privateStringgenderName;
publicStringgetGenderName(){
returngenderName;
}
Gender(intid,StringgenderName){
this.id=id;
this.genderName=genderName;
}
publicstaticGendergetGender(intid){
for(Gendergender:values()){
if(gender.id==id){
returngender;
}
}
returnM;
}
publicstaticGendergetGender(StringgenderName){
for(Gendergender:values()){
if(gender.genderName==genderName){
returngender;
}
}
returnM;
}
}
实现PropertyEditor
Person类中有5个字段,分别使用String、int、Gender、Date和boolean这5中类型,其中对String类型变量name我们使用PropertyEditorSupport这个默认实现就可以了,其他的类型我们需要自定义去实现PropertyEditor接口--int对应IntegerPropertyEditor、Gender对应GenderPropertyEditor、Date对应DatePropertyEditor以及boolean对应BooleanPropertyEditor。
IntegerPropertyEditor
IntegerPropertyEditor类继承了PropertyEditorSupport类和实现PropertyEditor接口(个人习惯实现接口的时候同时继承一个默认实现,这样我可以只关心我所需要实现的方法,当然,这个默认实现最好是一个抽象类),重写了getAsText()方法和setAsText(Stringtext),其代码如下:
@Override
publicStringgetAsText(){
returnString.valueOf((int)getValue());
}
@Override
publicvoidsetAsText(Stringtext)throwsIllegalArgumentException{
try{
setValue(Integer.parseInt(text));
}catch(NumberFormatExceptione){
thrownewIllegalArgumentException(e);
}
}
GenderPropertyEditor
GenderPropertyEditor主要是将外部获得到的字符串去转换为Gender,其实现思路是,先尝试将该字符串转换为Integer类型,如果转换成功则将转换得到Integer值通过Gender枚举的静态方法getGender(intid)获取Gender类型的变量;如果转换失败,则将该字符串看作genderName,再去获取Gender。至于Gender到字符串,直接返回genderName就可以了。主要代码如下:
@Override
publicStringgetAsText(){
Gendervalue=(Gender)getValue();
returnvalue.getGenderName();
}
@Override
publicvoidsetAsText(Stringvalue)throwsIllegalArgumentException{
try{
setValue(Gender.getGender(Integer.valueOf(value)));
}catch(NumberFormatExceptionex){
setValue(Gender.getGender(value));
}
}
DatePropertyEditor
DatePropertyEditor的思路和GenderPropertyEditor相似,其核心代码献上:
privateDateFormatdf;
@Override
publicStringgetAsText(){
Datedate=(Date)getValue();
returndf.format(date);
}
@Override
publicvoidsetAsText(Stringtext)throwsIllegalArgumentException{
try{
setValue(df.parse(text));
}catch(ParseExceptione){
thrownewIllegalArgumentException(e);
}
}
publicDatePropertyEditor(){
super();
this.df=newSimpleDateFormat("yyyy-MM-dd");
}
BooleanPropertyEditor
BooleanPropertyEditor与IntegerPropertyEditor一样,实现非常类似:
@Override
publicStringgetAsText(){
returnString.valueOf((boolean)getValue());
}
@Override
publicvoidsetAsText(Stringtext)throwsIllegalArgumentException{
setValue(Boolean.valueOf(text));
}
自定义BeanInfo
定义PersonBeanInfo类,用于描述Person属性和相对应的PropertyEditor。代码如下:
publicclassPersonBeanInfoextendsSimpleBeanInfoimplementsBeanInfo{
@Override
publicPropertyDescriptor[]getPropertyDescriptors(){
Listlist=newArrayList<>();
try{
//将Person中name与PropertyEditorSupport绑定
PropertyDescriptornamePropertyDescriptor=newPropertyDescriptor("name",Person.class);
namePropertyDescriptor.setPropertyEditorClass(PropertyEditorSupport.class);
//将Person中age与IntegerPropertyEditor绑定
PropertyDescriptoragePropertyDescriptor=newPropertyDescriptor("age",Person.class);
agePropertyDescriptor.setPropertyEditorClass(IntegerPropertyEditor.class);
//将Person中gender与GenderPropertyEditor绑定
PropertyDescriptorgenderPropertyDescriptor=newPropertyDescriptor("gender",Person.class);
genderPropertyDescriptor.setPropertyEditorClass(GenderPropertyEditor.class);
//将Person中birthday与DatePropertyEditor绑定
PropertyDescriptorbirthdayPropertyDescriptor=newPropertyDescriptor("birthday",Person.class);
birthdayPropertyDescriptor.setPropertyEditorClass(DatePropertyEditor.class);
//将Person中married与BooleanPropertyEditor绑定
PropertyDescriptormarriedPropertyDescriptor=newPropertyDescriptor("married",Person.class);
marriedPropertyDescriptor.setPropertyEditorClass(BooleanPropertyEditor.class);
list.add(namePropertyDescriptor);
list.add(agePropertyDescriptor);
list.add(genderPropertyDescriptor);
list.add(birthdayPropertyDescriptor);
list.add(marriedPropertyDescriptor);
returnlist.toArray(newPropertyDescriptor[list.size()]);
}catch(IntrospectionExceptionex){
ex.printStackTrace();
}
returnnull;
}
}
创建配置文件
因为我创建的是一个普通的Java项目,因此我选择在src目录下创建person.properites文件,文件内容如下:
name=arthurming age=18 gender=1 birthday=2017-10-24 married=true
测试
测试代码
@Test
publicvoidtest()throwsIOException,IllegalAccessException,IllegalArgumentException,InvocationTargetException,InstantiationException{
Propertiesp=newProperties();
InputStreamis=this.getClass().getClassLoader().getResourceAsStream("person.properties");
p.load(is);
BeanInfobeanInfo=newPersonBeanInfo();
PropertyDescriptor[]propertyDescriptoies=beanInfo.getPropertyDescriptors();
Personperson=newPerson();
for(PropertyDescriptorpropertyDescriptor:propertyDescriptoies){
Stringkey=propertyDescriptor.getName();
Stringvalue=p.getProperty(key);
Methodmethod=propertyDescriptor.getWriteMethod();
PropertyEditorpe=(PropertyEditor)propertyDescriptor.getPropertyEditorClass().newInstance();
if(pe.getClass()==PropertyEditorSupport.class){//①
pe.setValue(value);
}else{
pe.setAsText(value);
}
method.invoke(person,pe.getValue());
}
System.out.println(person);
}
说明:代码①表示当pe类型是PropertyEditorSupport,而不是我所定义PropertyEdtior,应该使用setValue方法而不是setAsText方法。
因为在PropertyEditorSupport中,其setAsText()方法为:
publicvoidsetAsText(Stringtext)throwsjava.lang.IllegalArgumentException{
if(valueinstanceofString){
setValue(text);
return;
}
thrownewjava.lang.IllegalArgumentException(text);
}
如果使用setAsText()方法,那么由于value不是String类型,将会抛出IllegalArgumentException。不过很遗憾我搞明白value到底实际上什么类型......
测试结果
Person[name=arthurming,age=18,gender=M,birthday=TueOct2400:00:00CST2017,married=true]
小结
感觉您能容忍我拙劣的文笔看到现在,也希望你在读《精通Spring+4.x++企业应用开发实战》这本书时,看到有关JavaBean编辑器的知识,我的这个例子可以对你有所帮助。
以上这篇基于JavaBean编辑器读取peroperties文件的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。