内省(Introspector) — JavaBean
什么是JavaBean和字段/属性的读写方法?
1 什么是JavaBean?有何特征?
1)符合特定规则的类
2)JavaBean分二类:
a)狭义的JavaBean
.私有的字段(Field)
.对私有字段提供存取方法(读写方法)
b)广义的JavaBean
.私有的字段(Field)
.对私有字段提供存取方法(读写方法)
.数量任意的业务方法
1、所有属性为private
2、提供默认构造方法
3、提供getter和setter
4、实现serializable接口
访问JavaBean属性的两种方式:
直接调用bean的setXXX或getXXX方法。
通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式。
通过PropertyDescriptor类操作Bean的属性
通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
2 内省API(SUN公司开发)站在反射角度
1)在操作JavaBean时,即对JavaBean进入setter和getter操作时
2)属性和getXxxxx()有关,同时必须有返回值
3)任何一个JavaBean都有一个class属性,来自于Object类。
*3 BeanUtils框架/工具(APACHE开源组织开发)
1)BeanUtils框架能够完成内省的一切功能,而且优化
利用内省操作javabean属性
public void test1() throws Exception{
Student s = new Student();
PropertyDescriptor pd = new PropertyDescriptor("name",Student.class);
Method m = pd.getWriteMethod();
m.invoke(s,"jack"); //new Student().setName("jack")
m = pd.getReadMethod();
String name = (String)m.invoke(s,null); //new Student().getName()
System.out.println("name="+name);
}
public void test2() throws Exception{
BeanInfo bi = Introspector.getBeanInfo(Student.class);
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
for(PropertyDescriptor pd : pds){
System.out.println(pd.getName());
}
}
2)BeanUtils框架能够对String<->基本类型自动转化
3)BeanUtils框架自定义转换器:
ConvertUtils.register( 转换规则 ,目标对象的Class)
4)向BeanUtils框架注册自定义转换器必须放在bu.setProperty()代码之前
5)使用BeanUtils内置String->Date的转换器:
ConvertUtils.register(new DateLocaleConverter(),java.util.Date.class);
定义一个student类
package cn.itcast.java.beanutils;
import java.util.Date;
//侠义JavaBean
public class Student {
private String name;
private int age;
private Date birthday;
public Student(){}
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;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
通过3 BeanUtils框架/工具
package cn.itcast.java.beanutils;
import java.util.Date;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Test;
public class Demo1 {
@Test
public void test1() throws Exception{
Student s = new Student();
BeanUtils bu = new BeanUtils();
Constructor Summary
Constructors
Constructor and Description
/*3)BeanUtils框架自定义转换器:ConvertUtils.register( 转换规则 ,目标对象的Class)
//向BeanUtils框架注册自定义的转换器(String->java.util.Date)
ConvertUtils.register(new Converter(){
public Object convert(Class clazz, Object type) {
//参数一:java.util.Date.class(目标类型)
//参数二:是传入的参数类型,即java.lang.String
String strBirthday = (String) type;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(strBirthday);
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
},java.util.Date.class);
*/
//DateLocaleConverter内置本地转换器
ConvertUtils.register(new DateLocaleConverter(),java.util.Date.class);
bu.setProperty(s,"name","张三");
bu.setProperty(s,"age","31");//BeanUtils框架能够对String<->基本类型自动转化
bu.setProperty(s,"birthday","2011-10-09");//BeanUtils框架注册自定义的转换器(String->java.util.Date)
String name = bu.getProperty(s,"name");
String age = bu.getProperty(s,"age");
String birthday = bu.getProperty(s,"birthday");
System.out.println("name="+name);
System.out.println("age="+age);
System.out.println("birthday="+new Date(birthday).toLocaleString());
}
}
使用另外一套API进行操作
package cn.itcast.java.introspector;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import org.junit.Test;
public class Demo1 extends Object{
@Test
public void test1() throws Exception{
Student s = new Student();
//pd引用Student的name属性
PropertyDescriptor pd = new PropertyDescriptor("name",Student.class);
//m = setName()
Method m = pd.getWriteMethod();
//s.setName("berry")
m.invoke(s,"berry");
//s.getName()
m = pd.getReadMethod();
String returnValue = (String) m.invoke(s,null);
System.out.println("returnValue="+returnValue);
}
//returnValue=berry
@Test
public void test2() throws Exception{
//BeanInfo表示该Student对象所有的属性情况
BeanInfo bi = Introspector.getBeanInfo(Student.class);
//取得Student对象所有属性集合
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
for(PropertyDescriptor pd : pds){
System.out.println(pd.getName());
/*
age
birthday
class
name
*/
}
}
}