关于Java反射机制的一个实例

    *
      关于Java反射机制的一个实例
    * http://developer.51cto.com  2009-06-19 13:59  abruzzi  javaeye  我要评论(0)

      本文向您展示Java反射机制的一个实例,该实例持简单EL的taglib,基本上实现了多级bean的属性的访问。

      JSP的规范中,有个表达式语言(Expression Language, 简称EL),可以算是一个微型的语言,其中对request, page, session, application中预存的JavaBean对象的引用方式很是简单。最近正好需要写一个支持简单EL的taglib,所以就研究了下Java反射机制,目前基本上实现了多级bean的属性的访问,经测试,还是可以用的。如:

         1. public static void main(String[] args){ 
         2.     UserBean bean = new UserBean(); 
         3.     bean.setName("John Abruzzi"); 
         4.     bean.setNick("Abruzzi"); 
         5.     bean.setAge(24); 
         6.      
         7.     AddressBean addr = new AddressBean(); 
         8.     addr.setZip("0086"); 
         9.     addr.setStreet("Bell Street #12"); 
        10.     bean.setAddress(addr); 
        11.      
        12.     System.out.println(BeanParser.doParse(bean, "bean.address.street")); 
        13.     System.out.println(BeanParser.doParse(bean, "bean.address.zip")); 
        14.     System.out.println(BeanParser.doParse(bean, "bean.name")); 
        15.     System.out.println(BeanParser.doParse(bean, "bean.nick")); 
        16.     System.out.println(BeanParser.doParse(bean, "bean.age")); 
        17. }

      需要可以输出:

         1. Bell Street #12
         2. 0086
         3. John Abruzzi 
         4. Abruzzi 
         5. 24

      反射,即由一个抽象的对象(如Object),取出这个具体对象的属性或者方法(就EL中关于Bean的引用来说,这个定义已经够了)。在EL中,对一个Bean的某字段进行引用,只需 ${bean.field},当然,这个bean是已经被set到容器中的,这就是Java反射机制。

      我们从容器中取出以bean为名字的Object,通过Java反射机制知道它的真实类型,然后通过field以javabean规范拼出方法名,进行调用,如果这个表达式是多级的,如${bean.field.field},其中第一个field本身就是一个bean对象,同样需要递归的进行解析。

      大概原理就是这些了,看代码吧:

      现有一个UserBean, 其中的一个字段Address本身又是一个AddressBean。

         1. package elparser; 
         2. 
         3. public class AddressBean { 
         4.     private String street; 
         5.     private String zip; 
         6.      
         7.     public String getZip() { 
         8.         return zip; 
         9.     } 
        10. 
        11.     public void setZip(String zip) { 
        12.         this.zip = zip; 
        13.     } 
        14. 
        15.     public String getStreet() { 
        16.         return street; 
        17.     } 
        18. 
        19.     public void setStreet(String street) { 
        20.         this.street = street; 
        21.     } 
        22.      
        23. }

      然后是UserBean

         1. package elparser; 
         2. 
         3. public class UserBean { 
         4.     private String name; 
         5.     private String nick; 
         6.     private AddressBean address; 
         7.     private int age; 
         8.      
         9.     public int getAge(){ 
        10.         return this.age; 
        11.     } 
        12.      
        13.     public void setAge(int age){ 
        14.         this.age = age; 
        15.     } 
        16.      
        17.     public String getName() { 
        18.         return name; 
        19.     } 
        20.     public void setName(String name) { 
        21.         this.name = name; 
        22.     } 
        23.     public String getNick() { 
        24.         return nick; 
        25.     } 
        26.     public void setNick(String nick) { 
        27.         this.nick = nick; 
        28.     } 
        29.     public AddressBean getAddress() { 
        30.         return address; 
        31.     } 
        32.     public void setAddress(AddressBean address) { 
        33.         this.address = address; 
        34.     } 
        35. }

      Bean都是很简单的,考虑到对基本类型的支持,所以在UserBean中加入一个int型的字段age

      好了,看看怎么通过一个串和一个对象来取出其中的字段来:

         1. package elparser; 
         2. 
         3. import java.lang.reflect.Method; 
         4. 
         5. public class BeanParser { 
         6.      
         7.     private static String getMethodName(String property, String prefix){ 
         8.         String prop = Character.toUpperCase(property.charAt(0))+property.substring(1); 
         9.      
        10.         String methodName = prefix + prop; 
        11.      
        12.         return methodName; 
        13.     } 
        14.      
        15.     private static Object parse(Object bean, String expr){ 
        16.         Class beanClass = bean.getClass(); 
        17.          
        18.         Method method = null; 
        19.         Object result = null; 
        20.          
        21.         try{ 
        22.             //这两步是关键,get方法不需要传入参数,所以只是new出两个空数组传入 
        23.             method = beanClass.getMethod(getMethodName(expr, "get"), new Class[]{}); 
        24.             result = method.invoke(bean, new Object[]{}); 
        25.         }catch(Exception e){ 
        26.             System.out.println(e.getMessage()); 
        27.         } 
        28.          
        29.         return result; 
        30.     } 
        31.      
        32.     public static Object doParse(Object bean, String expr){ 
        33.         String keys[] = expr.split("\\."); 
        34.          
        35.         Object obj = null; 
        36.          
        37.         for(int i = 1; i < keys.length;i++){ 
        38.             obj = parse(bean, keys[i]); 
        39.             bean = obj; 
        40.         }//递归parse 
        41.          
        42.         return obj; 
        43.     } 
        44.      
        45.     public static void main(String[] args){ 
        46.         UserBean bean = new UserBean(); 
        47.         bean.setName("John Abruzzi"); 
        48.         bean.setNick("Abruzzi"); 
        49.         bean.setAge(24); 
        50.          
        51.         AddressBean addr = new AddressBean(); 
        52.         addr.setZip("0086"); 
        53.         addr.setStreet("Bell Street #12"); 
        54.         bean.setAddress(addr); 
        55.          
        56.         System.out.println(BeanParser.doParse(bean, "bean.address.street")); 
        57.         System.out.println(BeanParser.doParse(bean, "bean.address.zip")); 
        58.         System.out.println(BeanParser.doParse(bean, "bean.name")); 
        59.         System.out.println(BeanParser.doParse(bean, "bean.nick")); 
        60.         System.out.println(BeanParser.doParse(bean, "bean.age")); 
        61.     } 
        62. }

      代码比较简短,重要部分有注释,应该很容易理解。当然这篇文章主要是关于Java的反射机制,如果需要对EL完全支持,可以使用JavaCC做一个简单的分析器(Apache的commons中包含一个el的项目,就是用javacc写的分析器)。

      【编辑推荐】
         1. 在Java应用程序中使用Jfreechart配置
         2. Java程序员学习Flex和BlazeDS的十三个理由
         3. 用JavaFX编写用户界面控制器
         4. Java WEB开发中的中文乱码问题解决
         5. 总结Java Web中几个函数的作用
      【责任编辑:red7 TEL:(010)68476606】

你可能感兴趣的:(java,bean,Flex,jfreechart,JavaFX)