内省(Introspector)和BeanUtils工具包
内省(Introspector)和BeanUtils工具包
内省(Introspector)
为什么要学内省?
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。
什么是Java对象的属性和属性的读写方法?
内省访问JavaBean属性的两种方式:
通过PropertyDescriptor类操作Bean的属性
通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的getter/setter 方法,然后通过反射机制来调用这些方法。
内省是 Java 语言对 Bean 类属性的一种缺省处理方法。例如类 A 中有属性 name, 可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这是默认的规则。 Java 中提供了一套 API 来访问某个属性的 getter/setter 方法。
一般的做法是通过类Introspector 来获取某个对象的BeanInfo 信息,然后通过BeanInfo 来获取属性的描述器(PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法
内省—beanutils工具包
Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert,Class clazz)
自定义转换器
练习:
l 请使用sun 内省api得到某一个bean的所有属性,并操作bean的其中一个属性(给属性赋值,以及得到属性的值) ,
package com.hbsi.csdn;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
/**
* 使用sun 内省api得到某一个bean的所有属性,并操作bean的其中一个属性(给属性赋值,以及得到属性的值)
* @author lenovo
*
*/
public class SunBeanDemo {
/**
* @param args
*/
public static void main(String[] args) {
SunBeanDemo sbd=new SunBeanDemo();
try {
sbd.Test();
} catch (Exception e) {
e.printStackTrace();
}
}
public void Test() throws Exception{
Person p=new Person();
BeanInfobi=Introspector.getBeanInfo(Person.class);
//BeanInfobi=Introspector.getBeanInfo(Person.class,Object.class);
PropertyDescriptor[]pds=bi.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
String name=pd.getName();
System.out.println(name);
/*if(name.equals("name")){
Method m=pd.getWriteMethod();
m.invoke(p, "song");
}*/
}
//System.out.println(p.getName());
p.setName("song");
PropertyDescriptor pdc=newPropertyDescriptor("name", p.getClass());
Method m=pdc.getReadMethod();
String str=(String) m.invoke(p, null);
System.out.println(str);
}
}
//Bean
class Person{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
l .请使用beanUitls框架操作bean的属性,然后会自定义转换器
package com.hbsi;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
importorg.apache.commons.beanutils.BeanUtils;
importorg.apache.commons.beanutils.ConversionException;
importorg.apache.commons.beanutils.ConvertUtils;
importorg.apache.commons.beanutils.Converter;
public class BeanUtilDemo {
/**
* @param args
*/
public static void main(String[] args) {
BeanUtilDemo bud=new BeanUtilDemo();
try {
bud.Test();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void Test() throws Exception{
ConvertUtils.register(new Converter(){
@Override
public Object convert(Class type, Objectvalue) {
if(value==null){
return null;
}
if(!(value instanceof String)){
throw new ConversionException("只能转换String类型");
}
String s=(String) value;
if(s.trim().equals("")){
return null;
}
SimpleDateFormat sdf=newSimpleDateFormat("yyyy-MM-dd");
try {
Date d=sdf.parse(s);
return d;
} catch (ParseException e) {
throw new ConversionException("转换错误");
}
}
}, Date.class);
String name1="song";
String age1="21";
String birthday1="1991-10-15";
Person p=new Person();
BeanUtils.setProperty(p, "name",name1);
BeanUtils.setProperty(p, "age",age1);
BeanUtils.setProperty(p, "birthday",birthday1);
System.out.println(p.getName()+"..."+p.getAge()+"..."+p.getBirthday().toLocaleString());
}
}
package com.hbsi;
import java.util.Date;
public class Person {
private String name;
private int age;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}