为什么要学内省?
开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。
内省是用于操作java对象的属性的,那么以下问题我们必须要清楚。
问题一: 什么是Java对象的属性和属性的读写方法?
问题二: 如何通过内省访问到javaBean的属性 ?
1. 通过PropertyDescriptor类操作Bean的属性.
public static void testPropertyDescriptor() throws Exception{ Person p = new Person(); PropertyDescriptor propertyDescriptor = new PropertyDescriptor("id",Person.class); //获取属性的写的方法。 Method writeMethod = propertyDescriptor.getWriteMethod(); Method readMethod = propertyDescriptor.getReadMethod(); propertyDescriptor.getReadMethod(); writeMethod.invoke(p, 12); System.out.println(readMethod.invoke(p, null)); }
2. 通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
1 public static void testIntrospector() throws Exception{ 2 BeanInfo beanInfo = Introspector.getBeanInfo(Person.class); 3 PropertyDescriptor[] descriptor = beanInfo.getPropertyDescriptors(); 4 for(PropertyDescriptor itemProperty : descriptor){ 5 System.out.println(itemProperty.getReadMethod().getName()); 6 } 7 }
存在的问题: sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils。
1 public static void main(String[] args) throws Exception { 2 Person p = new Person(); 3 ConvertUtils.register(new Converter() { 4 5 @Override 6 public Object convert(Class type, Object value) { 7 try { 8 if(value!=null){ 9 10 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy MM dd"); 11 Date d = dateFormat.parse((String) value); 12 return d; 13 } 14 } catch (ParseException e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 } 18 19 return null; 20 } 21 }, Date.class); 22 23 BeanUtils.setProperty(p,"id","110"); 24 BeanUtils.setProperty(p,"name","狗娃"); 25 BeanUtils.setProperty(p, "birthDay","1992 12 12"); 26 System.out.println(p.getId() +"=="+ p.getName()+"======"+p.getBirthDay()); 27 }
BeanUtils:
BeanUtils主要解决 的问题: 把对象的属性数据封装 到对象中。
BeanUtils的好处:
1. BeanUtils设置属性值的时候,如果属性是基本数据 类型,BeanUtils会自动帮我转换数据类型。
2. BeanUtils设置属性值的时候底层也是依赖于get或者Set方法设置以及获取属性值的。
3. BeanUtils设置属性值,如果设置的属性是其他的引用 类型数据,那么这时候必须要注册一个类型转换器。
BeanUtilss使用的步骤:
1. 导包commons-logging.jar 、 commons-beanutils-1.8.0.jar
1 public class Demo3 { 2 3 public static void main(String[] args) throws Exception { 4 //从文件中读取到的数据都是字符串的数据,或者是表单提交的数据获取到的时候也是字符串的数据。 5 String id ="110"; 6 String name="陈其"; 7 String salary = "1000.0"; 8 String birthday = "2013-12-10"; 9 10 11 //注册一个类型转换器 12 ConvertUtils.register(new Converter() { 13 14 @Override 15 public Object convert(Class type, Object value) { // type : 目前所遇到的数据类型。 value :目前参数的值。 16 Date date = null; 17 try{ 18 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 19 date = dateFormat.parse((String)value); 20 }catch(Exception e){ 21 e.printStackTrace(); 22 } 23 return date; 24 } 25 26 }, Date.class); 27 28 29 Emp e = new Emp(); 30 BeanUtils.setProperty(e, "id", id); 31 BeanUtils.setProperty(e, "name",name); 32 BeanUtils.setProperty(e, "salary",salary); 33 BeanUtils.setProperty(e, "birthday",birthday); 34 35 36 System.out.println(e); 37 38 39 40 41 } 42 43 }