【原创】Spring的FileSystemXmlApplicationContext的模拟实现类

Junglesong 发表于 2006-12-17 09:41:31

看spring的ioc,感觉很点意思,观其源码无从下手,不知达人怎么看的,无奈之际,干脆自己写了一个Spring之FileSystemXmlApplicationContext的模拟类,贴出来请大家斧正.程序请见 
www.blogjava.net/Files/junglesong/MockSpringIoc.rar

1.功能说明:关于订单,折扣,价格
订单是货物的订单,主要货物有计算机,文具,纸张三类,还有其它一些物件.每种货物都有不同的折扣比例,从单价中扣除折扣比例后就是进货时的真实价格.

2.Spring之Ioc实现

这里就不赘述了,详情请见帖子
http://junglesong.yculblog.com/post.2618520.html

3.模拟实现

// 折扣接口

  1. public interface Discount{   
  2.  public float getDiscount();   
  3.  public void  setDiscount(float discount);   
  4. }  

// 计算机折扣类

  1. public class ComputerDiscount implements Discount{   
  2.  private float discount=0.0f;   
  3.     
  4.  public float getDiscount(){   
  5.   return discount;   
  6.  }   
  7.     
  8.  public void setDiscount(float discount){   
  9.   this.discount=discount;   
  10.  }   
  11. }  

// 文具折扣类

  1. public class StationaryDiscount implements Discount{   
  2.  private float discount=0.0f;   
  3.     
  4.  public float getDiscount(){   
  5.   return discount;   
  6.  }   
  7.     
  8.  public void setDiscount(float discount){   
  9.   this.discount=discount;   
  10.  }   
  11. }  

// 纸张折扣类

  1. public class PaperDiscount implements Discount{   
  2.  private float discount=0.0f;   
  3.     
  4.  public float getDiscount(){   
  5.   return discount;   
  6.  }   
  7.     
  8.  public void setDiscount(float discount){   
  9.   this.discount=discount;   
  10.  }   
  11. }  

// 其它折扣类

  1. public class OtherDiscount implements Discount{   
  2.  private float discount=0.0f;   
  3.     
  4.  public float getDiscount(){   
  5.   return discount;   
  6.  }   
  7.     
  8.  public void setDiscount(float discount){   
  9.   this.discount=discount;   
  10.  }   
  11. }   

// 订单类

  1. public class Order{   
  2.  public static final String Type_Computer="Computer";   
  3.  public static final String Type_Stationary="Stationary";   
  4.  public static final String Type_Paper="Paper";    
  5.  private String type;   
  6.     
  7.  private float price;    
  8.     
  9.  public Order(float price,String type){   
  10.   this.price=price;   
  11.   this.type=type;   
  12.  }   
  13.     
  14.  public Order(){   
  15.   this(100.0f,"Other");   
  16.  }   
  17.   
  18.   
  19.  // 调用模拟类的地方,看看调用过程和Spring很相似吧 
  20.  public float getPrice() {   
  21.   MockContext ctx = new MockContext("bean.xml");   
  22.   Discount discount = null;   
  23.   discount = (Discount) ctx.getBean(this.type);   
  24.   
  25.   return price * (1.0f - discount.getDiscount());   
  26.  }   
  27. }   

 // Spring之FileSystemXmlApplicationContext的模拟类

  1. /**  
  2.  * Spring之FileSystemXmlApplicationContext的模拟类  
  3.  *   
  4.  * @author junglesong  
  5.  *  
  6.  */  
  7. public class MockContext {   
  8.  Document doc = null;// 用于解析Bean配置文件的Xml Document   
  9.  Element root = null;// Bean文件的根节点   
  10.   
  11.  /**  
  12.   * 构造函数,用于初始化doc和root  
  13.   * @param beanFileName  
  14.   */  
  15.  public MockContext(String beanFileName) {   
  16.   SAXBuilder buider = new SAXBuilder();   
  17.   try {   
  18.    doc = buider.build(new File(beanFileName));   
  19.    root = doc.getRootElement();   
  20.   
  21.   } catch (Exception ex) {   
  22.    ex.printStackTrace();   
  23.   }   
  24.  }   
  25.   
  26.  /**  
  27.   * 根据beanId创建类并调用规定的方法  
  28.   *   
  29.   * @param beanId  
  30.   * @return  
  31.   */  
  32.  public Object getBean(String beanId) {   
  33.   Object obj=null;   
  34.      
  35.   try {   
  36.    Element beanElm =getSubElm(root,"id",beanId);   
  37.       
  38.    if(beanElm!=null){   
  39.     String className=beanElm.getAttribute("class").getValue();   
  40.     Class cls=Class.forName(className);    
  41.     // 由类得到类实例   
  42.     obj=cls.newInstance();   
  43.        
  44.     List ls=beanElm.getChildren();       
  45.     for(Iterator it=ls.iterator();it.hasNext();){   
  46.      Element elm=(Element)it.next();   
  47.         
  48.      String methodName=elm.getAttributeValue("name");   
  49.      String methodValue=(String)elm.getChildText("value");    
  50.         
  51.      // 取得类方法   
  52.      Method method = cls.getMethod(getSetterMethod(methodName), new Class[] {getClassByValue(methodValue)});   
  53.         
  54.      // 建立数组   
  55.                     Object params[]=getParamsByValue(methodValue);   
  56.                                            
  57.                     // 调用类方法   
  58.      method.invoke(obj,params);   
  59.     }       
  60.    }      
  61.   } catch (Exception ex) {   
  62.    ex.printStackTrace();   
  63.   }   
  64.   
  65.   return obj;   
  66.  }   
  67.     
  68.  /**  
  69.   * 由参数的值得到参数的类型,目前可处理浮点数和字符串两种情况  
  70.   *   
  71.   * @param value  
  72.   * @return  
  73.   */  
  74.  private Class getClassByValue(String value){   
  75.   Class cls=String.class;   
  76.      
  77.   try{   
  78.    Float.parseFloat(value);   
  79.    cls=float.class;   
  80.   }   
  81.   catch(Exception ex){   
  82.    ex.printStackTrace();   
  83.   }     
  84.      
  85.   return cls;   
  86.  }   
  87.     
  88.  /**  
  89.   * 由参数的值得到包含参数的数组,目前可处理浮点数和字符串两种情况  
  90.   *   
  91.   * @param value  
  92.   * @return  
  93.   */  
  94.  private Object[] getParamsByValue(String value){   
  95.   Object[] params=new Object[1];   
  96.      
  97.   try{   
  98.    Float.parseFloat(value);   
  99.    params[0]=new Float(Float.parseFloat(value));   
  100.   }   
  101.   catch(Exception ex){   
  102.    ex.printStackTrace();   
  103.    params[0]=new String(value);   
  104.   }    
  105.      
  106.   return params;   
  107.  }   
  108.     
  109.  /**  
  110.   * 取得root下属性为subElmAttr,值等于subElmValue的节点  
  111.   *   
  112.   * @param root  
  113.   * @param subElmAttr  
  114.   * @param subElmValue  
  115.   * @return  
  116.   */  
  117.  private Element getSubElm(Element root,String subElmAttr,String subElmValue){   
  118.   Element rtv=null;   
  119.      
  120.   List ls=root.getChildren();   
  121.      
  122.   for(Iterator it=ls.iterator();it.hasNext();){   
  123.    Element elm=(Element)it.next();   
  124.       
  125.    if(elm.getAttribute(subElmAttr).getValue().equals(subElmValue)){   
  126.     rtv=elm;   
  127.     break;   
  128.    }   
  129.   }   
  130.      
  131.   return rtv;   
  132.  }   
  133.     
  134.  /**  
  135.   * 取得setter方法  
  136.   *   
  137.   * @param methodName  
  138.   * @return  
  139.   */  
  140.  private String getSetterMethod(String methodName){   
  141.   return "set"+methodName.substring(0,1).toUpperCase()+methodName.substring(1,methodName.length());   
  142.  }   
  143. }   
  144.   

 调用的代码如下:

java 代码
  1. Order computerOrder=new Order(100.0f,Order.Type_Computer);   
  2. System.out.println("computerOrder's price is \t"+computerOrder.getPrice());   
  3.   
  4. Order stationaryOrder=new Order(100.0f,Order.Type_Stationary);   
  5. System.out.println("stationaryOrder's price is \t"+stationaryOrder.getPrice());   
  6.   
  7. Order paperOrder=new Order(100.0f,Order.Type_Paper);   
  8. System.out.println("paperOrder's price is \t\t"+paperOrder.getPrice());   
  9.   
  10. Order otherOrder=new Order();   
  11. System.out.println("otherOrder's price is \t\t"+otherOrder.getPrice());  

输出效果和使用Spring是一样的,速度慢了些,但可以优化:

java 代码
  1. computerOrder's price is  70.0  
  2. stationaryOrder's price is  80.0  
  3. paperOrder's price is   90.0  
  4. otherOrder's price is   95.0  

 感悟: 有些关键性的框架要知其然知之其所以然,不能满足于使用.纸上得来终觉浅,绝知此事要躬行.实现完了再看源码也许更有感悟.

关键词(Tag): spring 反射 ioc


收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定