内省
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。
简单的说就是:内省是用于操作java对象的属性的。且内省机制是建立在属性的get和set方法上的。
内省涉及到的类:PropertyDescriptor、Introspector、BeanInfo
PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。
常用方法
构造方法
PropertyDescriptor(String propertyName, Class<?> beanClass)
通过调用 getFoo 和 setFoo 存取方法,为符合标准 Java 约定的属性构造一个 PropertyDescriptor。
获取get和set方法
Method
getReadMethod()
获得应该用于读取属性值的方法。
Method
getWriteMethod()
获得应该用于写入属性值的方法。
PropertyDescriptor代码示例:
1 //实体类---javaBean 2 public class Person { 3 4 private int id; 5 6 private String name; 7 8 public Person(int id, String name) { 9 super(); 10 this.id = id; 11 this.name = name; 12 } 13 14 public Person(){} 15 16 public int getId() { 17 return id; 18 } 19 20 public void setId(int id) { 21 this.id = id; 22 } 23 24 public String getName() { 25 return name; 26 } 27 28 public void setName(String name) { 29 this.name = name; 30 } 31 32 @Override 33 public String toString() { 34 35 return "编号:"+ this.id+" 姓名:"+ this.name; 36 } 37 38 } 39 //PropertyDescriptor 使用 40 public void testProperty() throws Exception{ 41 Person p = new Person(); 42 //属性描述器 43 PropertyDescriptor descriptor = new PropertyDescriptor("id", Person.class); 44 //获取属性对应的get或者是set方法设置或者获取属性了。 45 Method m = descriptor.getWriteMethod(); //获取属性的set方法。 46 //执行该方法设置属性值 47 m.invoke(p,110); 48 49 Method readMethod = descriptor.getReadMethod(); //是获取属性的get方法 50 51 System.out.println(readMethod.invoke(p, null)); 52 }
Introspector 类为通过工具学习有关受目标 Java Bean 支持的属性、事件和方法的知识提供了一个标准方法。
常用方法
static BeanInfo
getBeanInfo(Class<?> beanClass)
在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。
代码示例
1 public void getAllProperty() throws IntrospectionException{ 2 //Introspector 内省类 3 BeanInfo beanInfo = Introspector.getBeanInfo(Person.class); 4 //通过BeanInfo获取所有的属性描述其 5 PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); //获取一个类中的所有属性描述器 6 for(PropertyDescriptor p : descriptors){ 7 System.out.println(p.getReadMethod()); //get方法 8 } 9 }
BeanUtils
sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils。
BeanUtils是以jar包的形式提供的。所以使用前必须要要导入对应的jar包,且BeanUtils依赖于commons-logging.jar。
BeanUtils的好处:
1. BeanUtils设置属性值的时候,如果属性是基本数据 类型,BeanUtils会自动转换数据类型。
2. BeanUtils设置属性值的时候底层也是依赖于get或者Set方法设置以及获取属性值的。
3. BeanUtils设置属性值,如果设置的属性是其他的引用类型数据,那么这时候必须要注册一个类型转换器。
代码示例
1 //实体类-javaBean 2 public class Emp { 3 4 private int id; 5 6 private String name; 7 8 private double salary; 9 10 private Date birthday; 11 12 13 public Date getBirthday() { 14 return birthday; 15 } 16 17 public void setBirthday(Date birthday) { 18 this.birthday = birthday; 19 } 20 21 public int getId() { 22 return id; 23 } 24 25 public void setId(int id) { 26 this.id = id; 27 } 28 29 public String getName() { 30 return name; 31 } 32 33 public void setName(String name) { 34 this.name = name; 35 } 36 37 public double getSalary() { 38 return salary; 39 } 40 41 public void setSalary(double salary) { 42 this.salary = salary; 43 } 44 45 public Emp(int id, String name, double salary) { 46 super(); 47 this.id = id; 48 this.name = name; 49 this.salary = salary; 50 } 51 52 public Emp(){} 53 54 55 @Override 56 public String toString() { 57 return "编号:"+this.id+" 姓名:"+ this.name+ " 薪水:"+ this.salary+" 生日:"+ birthday; 58 } 59 60 } 61 62 //BeanUtils用法 63 public class Demo3 { 64 65 public static void main(String[] args) throws Exception { 66 //从文件中读取到的数据都是字符串的数据,或者是表单提交的数据获取到的时候也是字符串的数据。 67 String id ="110"; 68 String name="陈其"; 69 String salary = "1000.0"; 70 String birthday = "2013-12-10"; 71 72 73 //注册一个类型转换器 74 ConvertUtils.register(new Converter() { 75 76 @Override 77 public Object convert(Class type, Object value) { // type : 目前所遇到的数据类型。 value :目前参数的值。 78 Date date = null; 79 try{ 80 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 81 date = dateFormat.parse((String)value); 82 }catch(Exception e){ 83 e.printStackTrace(); 84 } 85 return date; 86 } 87 88 }, Date.class); 89 90 91 Emp e = new Emp(); 92 BeanUtils.setProperty(e, "id", id); 93 BeanUtils.setProperty(e, "name",name); 94 BeanUtils.setProperty(e, "salary",salary); 95 BeanUtils.setProperty(e, "birthday",birthday); 96 97 System.out.println(e); 98 } 99 100 }