内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。 Java 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些 API 存放于包 java.beans 中。 

一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。

为什么要学内省:

*****************************************

IntrosPector 是用来操作JavaBean类的;
所谓的javabean类其实是一个特殊的java类含有get和set方法的类。
三种方法:

1、使用PropertyDescriptor 属性描述符
PropertyDescriptor pd = newPropertyDescriptor(String propertyName,Class BeanClass);
getX()
Method getMethod =pd.getReadMethod();
set(类型  对象);
Method setMethod =pd.getWriteMethod(); 

2、使用Introspector 内省
BeanInfo beanInfo =Introspector.getBeanInfo(字节码比如:ReflectPoint.class);
再得到所有的属性描述符
PropertyDescriptor [] pds =beanInfo.getPropertyDescriptors();
然后可以进行迭代获得每个字段的值(使用get方法或使用set方法修改)


第三种使用了BeanUtils工具包,需要导入才能使用
3、直接使用BeanUtils类(静态方法)
BeanUtils.setProperty(,,);
BeanUtils.getProperty();


***************


开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。

内省访问javaBean属性的两种方式:

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

import org.junit.Test;

//使用内省api操作bean的属性

public class Demo4
{

//获得Bean的属性
    @Test
    public void test1() throws Exception
    {
	//这里获取了继承object方法的属性
	//BeanInfo info = Introspector.getBeanInfo(Person1.class);
	
	//只获取Person1的属性
	BeanInfo info = Introspector.getBeanInfo(Person1.class,Object.class);

	PropertyDescriptor[] pds = info.getPropertyDescriptors();
	
	for(PropertyDescriptor pd : pds)
	{
	    System.out.println(pd.getName());
	}
    }
    
//   操作Bean的属性
    
    @Test
    public void test2() throws Exception
    {
	Person1 p = new Person1();
	PropertyDescriptor pd = new PropertyDescriptor("age",Person1.class);
	//得到属性的写方法
	Method method = pd.getWriteMethod();//相当于获得setage方法
	method.invoke(p, 45);//给属性赋值
	
	
	//得到属性的值
	method = pd.getReadMethod();
	
	System.out.println(method.invoke(p, null));
	
    }
    
//    获取当前操作属性的类型
    @Test
    public void test3() throws Exception
    {
	Person1 p = new Person1();
	PropertyDescriptor pd = new PropertyDescriptor("age",Person1.class);
	System.out.println(pd.getPropertyType());
    }
 }