/**
* 1.JDK中的内省机制提供了对JavaBean的相关处理
* 2.理解内省,首先要明确在JavaBean中属性和实例变量的区别
* 3.通过该实例可以更好的理解框架在背后是如何操作JavaBean,以及EL,OGNL表达式对Bean属性的处理机制
* 4.是不是属性在于setter和getter方法,跟类的实例变量没有关系,但是为了缩写规范,尽量保证实例变量与属性命名一致
public class TestJavaBean{
private int x;//x是实例变量而不是属性
private int y;//y是实例变量也不是属性
public void setTime(){//time是属性,第二个字母为小写时,第一个字母变小写
}
public void getCPU(){//CPU是属性,第二个字母为大写时,第一个字母不变
}
}
*/
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
/**
*
* @author 钱亮亮
*
*/
public class IntroSpectorTest {
public static void main(String... args) throws Exception{
Point pt = new Point(4,6);
String propertyName = "x";
Object retVal = getProperty(pt,propertyName);
System.out.println(retVal);
Object value = 7;
setProperty(pt,propertyName,value);
System.out.println(pt.getX());
}
private static Object getProperty(Object pt, String propertyName) throws Exception{
/* 把类做为一个JavaBean来处理,获得所有的信息beanInfo,
通过beanInfo来获取所有的属性描述符,然后遍历查找符合条件的属性
BeanInfo beanInfo = Introspector.getBeanInfo(pt.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object retVal = null;
for(PropertyDescriptor pd : pds){
if(pd.getName().equals(propertyName)){
Method methodGetX = pd.getReadMethod();
retVal = methodGetX.invoke(pt);
break;
}
}*/
//通过class文件和属性名称来获取属性描述符对象
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt);
return retVal;
}
public static void setProperty(Object pt,String propertyName,Object value) throws Exception{
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt.getClass());
Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(pt, value);
}
}
class Point{
private int x;
private int y;
public Point(){}
public Point(int x, int y){
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
****************************************************
/**
* 1.在该实例中需要导入commons-beanutils.jar和commons-logging.jar(commons-beanutils.jar依赖于commons-logging.jar)
* 2.Apache的commons-beanutils.jar包对内省做了进一步的支持
*/
import java.util.Date;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
public class IntroSpectorTestByBeanUtils {
public static void main(String... args) throws Exception{
Person person = new Person("qll",26,new Date());
//Person必须是public修饰的,否则会报NoSuchMethodException
System.out.println(BeanUtils.getProperty(person, "name"));//qll
BeanUtils.setProperty(person, "name","mlh");
System.out.println(BeanUtils.getProperty(person, "name"));//mlh
System.out.println(BeanUtils.getProperty(person, "age"));//26
BeanUtils.setProperty(person, "age",30);
//BeanUtils支持把所有类型的属性都作为字符串处理
//在后台自动进行类型转换(字符串和真实类型的转换)
//因为在网络上,任何类型的数据都是以字符串的形式传输的
BeanUtils.setProperty(person, "age", "29");
System.out.println(BeanUtils.getProperty(person, "age"));//29
System.out.println(BeanUtils.getProperty(person, "age").getClass().getName());//java.lang.String
//BeanUtils支持对对象类型的导航处理,如testDate.time
//EL表达式和OGNL表达均采用类型的原理
System.out.println(BeanUtils.getProperty(person, "testDate"));//Tue Jan 26 14:27:06 CST 2010
BeanUtils.setProperty(person, "testDate.time", "111");
System.out.println(BeanUtils.getProperty(person, "testDate"));//Thu Jan 01 08:00:00 CST 1970
//PropertyUtils的功能类似于BeanUtils,但在底层不会对传递的数据做转换处理
PropertyUtils.setProperty(person, "age", 28);
System.out.println(PropertyUtils.getProperty(person, "age").getClass().getName());//java.lang.Integer
}
}
import java.util.Date;
public class Person{
private String name;
private int age;
private Date testDate;
public Person(){}
public Person(String name, int age, Date testDate){
this.name = name;
this.age = age;
this.testDate = testDate;
}
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 getTestDate() {
return testDate;
}
public void setTestDate(Date testDate) {
this.testDate = testDate;
}
}