Java 内省 Introspactor, BeanUtils

为什么要学内省?
•开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。
l什么是Java对象的属性和属性的读写方法?
l内省访问JavaBean属性的两种方式:
•通过PropertyDescriptor类操作Bean的属性
•通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器(PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter方法,然后通过反射机制来调用这些方法。

 

package com.gui.test;

import java.util.Date;

public class Dog {
 
 private String name;
 private int age;
 private String color;
 private Date birthday;
 
 public Date getBirthday() {
  return birthday;
 }
 public void setBirthday(Date birthday) {
  this.birthday = birthday;
 }
 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 String getColor() {
  return color;
 }
 public void setColor(String color) {
  this.color = color;
 } 
}

 

 

 

package com.gui.test;

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

import org.junit.Before;
import org.junit.Test;

public class DogTest {
 Dog dog;
 
 @Before
 public void before() throwsClassNotFoundException, InstantiationException,IllegalAccessException {
  Class clazz =Class.forName("com.gui.test.Dog");
  dog = (Dog)clazz.newInstance();
 }
 
 @Test
 public void testGetAllNames() throwsIntrospectionException {
  BeanInfo info = Introspector.getBeanInfo(Dog.class, Object.class);
  PropertyDescriptor[] pds =info.getPropertyDescriptors();
  for (PropertyDescriptor pd :pds) {
   System.out.println(pd.getName());
  }
 }
 
 @Test
 public void testGetAge() throwsIntrospectionException, IllegalArgumentException,IllegalAccessException, InvocationTargetException {
  
  
  PropertyDescriptor pd= new PropertyDescriptor("age", Dog.class);
  System.out.println(pd.getName());
  System.out.println(pd.getPropertyType());
  
  Method method =pd.getWriteMethod();
  method.invoke(dog,33);
  
  method =pd.getReadMethod();
  System.out.println(method.invoke(dog));
 }
}  

 

Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert, Class clazz)
自定义转换器

 

开发之前 要先引入 commons-beanutils-1.8.0.jar 和 commons-logging.jar包

 

 

package com.gui.test;

import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
importorg.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Before;
import org.junit.Test;

public class BeanUtilTest {
 Dog dog;
 
 @Before
 public void before() throwsClassNotFoundException, InstantiationException,IllegalAccessException {
  Class clazz =Class.forName("com.gui.test.Dog");
  dog = (Dog)clazz.newInstance();
 }
 
 @Test
 public void test1() throwsIllegalAccessException, InvocationTargetException,NoSuchMethodException {
  BeanUtils.setProperty(dog,"name", "kitty");
  System.out.println(BeanUtils.getProperty(dog,"name"));
 }
 
 @Test
 public void test2() throwsIllegalAccessException, InvocationTargetException,NoSuchMethodException {
  ConvertUtils.register(newDateLocaleConverter(), Date.class);//可自己实现Converter接口 日期转换
  BeanUtils.setProperty(dog,"name", "kitty");
  BeanUtils.setProperty(dog,"birthday", "2011-01-01");
  System.out.println(BeanUtils.getProperty(dog,"name"));
  System.out.println(BeanUtils.getProperty(dog,"birthday"));
 }
 
 
 @Test
 public void test3() throwsIllegalAccessException, InvocationTargetException,NoSuchMethodException {
  
  //为了让日期赋到bean的birthday属性上,我们给beanUtils注册一个日期转换器
  ConvertUtils.register(newConverter(){// 系统自动支持8种基本类型转换
   publicObject convert(Class type, Object value) {
    if(value==null){
     returnnull;
    }
    if(!(valueinstanceof String)){
     thrownew ConversionException("仅string类型的转换!!");
    }
    Stringstr = (String) value;
    if(str.trim().equals("")){
     returnnull;
    }
    
    SimpleDateFormatdf = new SimpleDateFormat("yyyy-MM-dd");
    try{
     returndf.parse(str);
    }catch (ParseException e) {
     thrownew RuntimeException(e);  //异常链不能断
    }
   }
  }, Date.class);
  
  Map map =new HashMap();
  map.put("name", "aaa");
  map.put("color", "red");
  map.put("age", "23");
  map.put("birthday","1980-09-09");
  
  ConvertUtils.register(newDateLocaleConverter(), Date.class);
  BeanUtils.populate(dog,map);   //用map集合中的值,填充bean的属性
  
  
  System.out.println(BeanUtils.getProperty(dog,"name"));
  System.out.println(BeanUtils.getProperty(dog,"color"));
  System.out.println(BeanUtils.getProperty(dog,"age"));
  System.out.println(BeanUtils.getProperty(dog,"birthday"));
 }
 
 
 
}

你可能感兴趣的:(Java 内省 Introspactor, BeanUtils)