内省和BeanUtils框架

内省(introspector):
                  beanutils内省框架(依赖commons-logging):apache
                  www.apache.org
            
      学内省的原因:  开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操 作过于麻烦,所以SUN公司开发了一套API,专门用于操作java对象的属性;
      通过内省技术访问(java.beans包提供了内省的API)JavaBean的两种方式:
                方式1:  通过Introspector类获得Bean对象的BeanInfo,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后通过反射机制来调用这些方法。
                方式2:  通过PropertyDescriptor类操作Bean的属性。           
                注:  属性指的是设置setter和读取getter字段的方法
                         属性名称是: getName()的属性名称是 name
                         属性的个数: 以get***()的个数来定  注意: 父类Object中还有一个getClass()的属性
                              
      内省-beanutil工具包:
                Beanutils是Apache开发的一套快速操作JavaBean getter/setter方法的API,目前比较流行;
                准备包:  commons-beanutils-1.8.3.jar(zip源码包) 和 commons-logging-1.1.1.jar(zip源码包)
                参考:      BeanUtils手册.html
                语法:
                        设置属性:  BeanUtils.setProperty(Object bean,String propertyName,String propertyValue);
                        获取属性:  BeanUtils.getProperty(Object bean,String PropertyName);
                应用:
                        BeanUtils将Map属性自动放到Bean中;
                        前提:  Map中的key必须要与Bean的属性一致
                        
                ******************************************************************************************************************************
                例1:   内省的基本原理
                            public class Student {
                                    private String name = "谢霆锋";  
                                    private int age = 20;
                                    private Date 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 Date getBirthday() {
                                            return birthday;
                                    }
                                    public void setBirthday(Date birthday) {
                                            this.birthday = birthday;
                                    }                                    
                            }
                            
                            
                            public class Demo {
                                  // 内省操作的是类中的属性(getter和setter方法)
                                  @Test
                                  public void test1() throws Exception{
                                          // 将Student类中的属性信息封装到BeanInfo的一个对象中
                                          BeanInfo bi = Introspector.getBeanInfo(Student.class);
                                          // 得到类中的所有属性描述器PropertyDescriptor
                                          PropertyDescriptor[] pds = bi.getPropertyDescriptors();                                    
                                          // 输出类/属性描述器中属性的个数,并遍历
                                          System.out.println(pds.length);
                                          for(PropertyDescriptor pd : pds){
                                            System.out.println(pd.getName());
                                          }
                                  }
                                  
                                  @Test
                                  public void test2() throws Exception{
                                          // 得到Student类中的name属性描述器  参数:属性名称和该属性所在类的字节码文件
                                          PropertyDescriptor pd = new PropertyDescriptor("name",Student.class);
                                          
                                          // 得到getName()方法属性(读方法)
                                          Method m1 = pd.getReadMethod();
                                          // 调用读方法属性并输出该字段的值
                                          Student s = new Student();
                                          String value = (String) m1.invoke(s, null);
                                          System.out.println(value);
                                          
                                          // 得到setName()方法属性(写方法),改变name字段的值
                                          Method m2 = pd.getWriteMethod();
                                          // 调用写方法并改变name字段的值
                                          m2.invoke(s, "陈冠希");
                                          System.out.println(s.getName());
                                  }
                                  
                                  
                                  // 利用BeanUtils框架操作属性,实现原理类似test2,是对上述3个方法的封装
                                  @Test
                                  public void test3() throws Exception{
                                          Student s = new Student();
                                          // 获取name字段的值 : 第一个参数为 对象, 第二个参数为 字段名称
                                          String str = BeanUtils.getProperty(s, "name");
                                          System.out.println(str);
                                          // 设置name字段的值:  参数为:  对象, 字段名称,   设置的新值
                                          BeanUtils.setProperty(s, "name", "新谢霆锋");
                                          System.out.println(s.getName());
                                  }
                                  
                                  
                                  // BeanUtils可以进行类型的自动转换,但仅限基本类型:
                                  // 如 :int->String(√);但 Date->String(×);  
                                  @Test
                                  public void test4() throws Exception{
                                          Student s = new Student();
                                          String str = BeanUtils.getProperty(s, "age");
                                          System.out.println(str);
                                      // BeanUtils.setProperty(s, "age", 30);
                                          BeanUtils.setProperty(s, "age", "30");
                                          System.out.println(s.getAge()); 
                                  }
                                  
                                  
                                  /*   注:  该方法会报错,无法实现非基本类型的自动转换
                                  @Test
                                  public void test5_1() throws Exception{
                                          Student s = new Student();
                                          String str = BeanUtils.getProperty(s, "birthday");
                                          System.out.println(str);
                                          BeanUtils.setProperty(s, "birthday", "1994-02-25");
                                          System.out.println(s.getBirthday()); 
                                  }
                                  */
                                  
                                  
                                  // 非基本类型的属性的设置:对非基本数据类型的转换 如: String<--->其他类型如 Date
                                  @Test
                                  public void test5_2() throws Exception{
                                          Student s = new Student();
                                          // 给BeanUtils注册类型转换器: 自定义转换器
                                          ConvertUtils.register(new Converter() {
                                                  // 参数  第一个type为: 目标类型,  第二个value为: 当前传入的值
                                                  public Object convert(Class type, Object value) {


                                                        //// 根据目标类型判断类型转换方式
                                                        //if(type.equals(Date.class)){
                                                        // // 字符串-->Date
                                                        //}else{
                                                        //// Date-->字符串
                                                        //}
                                                          
                                                          // 根据当前传入的值判断类型转换方式
                                                          DateFormat df = new SimpleDateFormat("yyyy-MM-dd");  
                                                          if(value instanceof String){
                                                                  // 字符串-->Date
                                                                  String v = (String)value;
                                                                  try {
                                                                          Date d =  df.parse(v);
                                                                          return d;
                                                                  } catch (ParseException e) {
                                                                          throw new RuntimeException(e);
                                                                  }
                                                          }else{
                                                                  // Date-->字符串
                                                                  Date d = (Date) value;
                                                                  return df.format(d);
                                                          }
                                                  }}, Date.class);
                                          BeanUtils.setProperty(s, "birthday", "1994-02-26");
                                          System.out.println(s.getBirthday());
                                  }


                                  
                                  @Test  // 使用已经封装好的BeanUtils中的日期转换器,日期转换器原理参考test5
                                  public void test5_3() throws Exception{
                                          Student s = new Student();
                                          // 给BeanUtils注册类型转换器: 自定义转换器
                                          ConvertUtils.register(new DateLocaleConverter(), Date.class);
                                          BeanUtils.setProperty(s, "birthday", "1994-02-26");
                                          System.out.println(s.getBirthday());
                                  }
                            }
                            
        ********************************************************************************************************************
            例2:   利用BeanUtils将Map中的数据封装到Bean中
                         public class Person {
                                  private String name;
                                  private int age;
                                  private Date 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 Date getBirthday() {
                                          return birthday;
                                  }
                                  public void setBirthday(Date birthday) {
                                          this.birthday = birthday;
                                  }
                                  @Override
                                  public String toString() {
                                          return "Person [age=" + age + ", birthday=" + birthday + ", name="
                                              + name + "]";
                                  }
                          }
   
                          // 利用BeanUtils封装数据
                          public class Demo {
                                    @Test
                                    public void test() throws Exception{
                                            Map map = new HashMap(); // map中的key与属性一致
                                            map.put("name", "小王");
                                            map.put("age", "30");
                                            map.put("birthday", "1994-02-22");
                                            
                                            Person p = new Person();
                                            System.out.println("封装数据前:" + p);
                                            
                                            // 通过转换器将非基本类型数据转换成字符串,然后再将Map中的属性统一封装到Bean中
                                            ConvertUtils.register(new DateLocaleConverter(),Date.class);
                                            BeanUtils.populate(p, map);
                                            
                                            System.out.println("封装数据后:" + p);
                                    }                            
                          }
                                                  
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                        
                
                       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值