反射机制的应用

来源:互联网 发布:js元素节点举例 编辑:程序博客网 时间:2024/04/30 19:56

           前边一篇博客写过相关反射机制的基础知识:java中的反射机制。写完这篇后有一条评论“反射反射程序员的快乐”,为什么说“快乐呢”,咱们看看反射的强大功能吧!这篇博客简单说一下反射机制的运用。

 

       反射机制,很多来说是Java中比较那学的东西,为什么?很多说是因为它比较抽象!说的也对,因为理解不了么,所以比较抽象。但是经过项目实践,框架的深究,感觉到反射有着强大的作用。是很多优秀框架的技术根源,是实现复用,达到解耦合的有利得手。因为反射不需要直到类,xml文件,等等的内容,只需要我们提前制定一种规则,那么我们就可以通过反射使我们的系统达到异常灵活的地步,使我们的开发有了那些提前写好可复用的代码——框架,这些可都是基于反射的强大作用。


         从现实生活中,我们找个反射的例子吧?什么类似Java中的反射机制呢???画家,它会画人像。来人出钱画个上学的学生,他马上画出来了;有来人出钱画个收小麦的农民,他也画出来了……     这就像我们的反射,过来什么类我们进行反射获取具体的类,就可以用它了,不用提前知道传过来的类的具体。而假如我们传统的new对象的画,必须知道传过来的对象,这样就很难达到多态的效果了。就像这个画家,如家就会画上学的儿童,那么那些想让他画农民的客户来了,就白跑了,这样显得画家的水平特别低了。转到我们的软件就是软件的功能特别单一了。


         那么通过反射在那些地方用的到呢?这里举两个例子:


         一,1,问题描述:一般在servlet或者anction类中,我们通过获取request中的数据,进行数据的封装,需要利用requestgetParameter一一取出数据来,然后再通过对象的set方法进行赋值,这样来看是非常麻烦呢?


       2,问题解决:通过反射我们可以不用知道request传过来的数据,只需要知道我们要封装的对象,就可以进行赋值,一次代码重复利用,达到了很好的复用效果。

              我们来看这个工具类:

[java] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;">  /** 
  2.      * 工具类 
  3.      * @author Administrator 
  4.      */  
  5.     public class WebUtil {  
  6.       
  7.         /** 
  8.          * 通过反射机制将request对象中保存的数据设置到某个java对象中。 
  9.          * @param request  请求对象,该对象中保存了用户从表单中提交的数据 
  10.          * @param o java对象 
  11.          */  
  12.         public static void makeRequestToObject(HttpServletRequest request,Object o){  
  13.             //获取类型  
  14.             Class c = o.getClass();  
  15.               
  16.             //获取用户提交所有数据的name  
  17.             Enumeration<String> names = request.getParameterNames();  
  18.             //循环所有的name  
  19.             while(names.hasMoreElements()){  
  20.                 //这里的name就是用户提交数据“=”左边的值  
  21.                 String name = names.nextElement();  
  22.                 //拼接方法名  
  23.                 String methodName = "set" + name.toUpperCase().charAt(0) + name.substring(1);  
  24.                 //获取方法  
  25.                 try {  
  26.                     Method setMethod = c.getMethod(methodName, String.class);  
  27.                     //执行set方法,进行赋值  
  28.                     setMethod.invoke(o, request.getParameter(name));  
  29.                 } catch (Exception e) {  
  30.                 }   
  31.             }  
  32.         }  
  33.     }  
  34. </span>  

        3,注意事项:当然,这里需要我们满足javabean规范,而且jsp页面的字段和bean里边的要一样等,就有一些规范了。



          二,1,问题描述:一般三层架构和MVC架构的层与层之间实现解耦合,而直接的分层加接口,耦合度还是很高的,如何使之间彼此不受影响呢?

        

        2,问题解决:利用反射:

[java] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;"public static void createService(){  
  2.                    // 创建所有的Service对象  
  3.                  // 利用XPATH指定查询条件  
  4.         xpath = "//bean[@type='service']";  
  5.   
  6.         // 获取所有的service类型的节点  
  7.         List<Element> serviceNodeList = doc.selectNodes(xpath);  
  8.   
  9.         // 创建每一个service类型的对象,并存储到临时的内存空间中。  
  10.         for (Element serviceElement : serviceNodeList) {  
  11.             // 解析属性值  
  12.             String id = serviceElement.attributeValue("id");  
  13.             String className = serviceElement.attributeValue("class");  
  14.             // 反射创建对象  
  15.             Object serviceObject = Class.forName(className).newInstance();  
  16.             // 得到业务对象的类  
  17.             Class serviceClass = serviceObject.getClass();  
  18.             // 保存到临时的map集合中  
  19.             serviceObjectMap.put(id, serviceObject);  
  20.   
  21.             // 这里需用将此service和dao的对象进行组合,利用本身的set方法  
  22.             List<Element> propertyElements = serviceElement.elements("property");  
  23.             for (Element proElement : propertyElements) {  
  24.   
  25.                 String fieldName = proElement.attributeValue("name");  
  26.                 String refId = proElement.attributeValue("refId");  
  27.                 // 获取关联对象  
  28.                 Object daoObject = daoObjectMap.get(refId);  
  29.                 // 获取对应的方法  
  30.                 String methodName = "set"+ fieldName.substring(01).toUpperCase()+ fieldName.substring(1);  
  31.   
  32.                 // 获取属性  
  33.                 Field fieldObj = serviceClass.getDeclaredField(fieldName);  
  34.                 Class fieldClazz = fieldObj.getType();  
  35.   
  36.                 // 获取属性的set方法  
  37.                 Method methodOjbect = serviceClass.getDeclaredMethod(methodName,fieldClazz);  
  38.   
  39.                 // 利用反射调用set方法,组合对象关系  
  40.                 methodOjbect.invoke(serviceObject, daoObject);  
  41.   
  42.             }  
  43.         }  
  44.           }  
  45. </span>  



       当然需要我们的xml文件来进行一些约束,有了一些规范:

[html] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;">  <?xml version="1.0" encoding="UTF-8"?>  
  2.     <beans>  
  3.         <!-- 声明Dao层的对象 -->  
  4.         <bean id="userDao"  type="dao" class="com.ljh.system.dao.impl.UserDaoImpl"></bean>  
  5.           
  6.         <!-- 声明Service对象 -->  
  7.         <bean id="userService"  type="service" class="com.ljh.system.service.impl.UserServiceImpl">  
  8.             <property name="userDao" refId="userDao"></property>  
  9.         </bean>  
  10.       
  11.         <!-- 声明Action对象 -->  
  12.         <bean id="userAction" type="action" class="com.ljh.system.action.UserAction">  
  13.             <property name="userService" refId="userService"></property>  
  14.         </bean>  
  15.     </beans>  
  16. </span>  

         这里是一个利用反射获取了service类,并且关联了dao类,感觉反射的作用是非常强大的。

         

         通过项目的实践,不仅加深了对反射机制的理解,更感觉到了它的无限魅力,有了反射,感觉很多问题都迎刃而解了!



0 0
原创粉丝点击