信手拈来 妙手偶得 » 日志 » 【原创】Spring的FileSystemXmlApplicationContext的模拟实现类
【原创】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.模拟实现
// 折扣接口
- public interface Discount{
- public float getDiscount();
- public void setDiscount(float discount);
- }
// 计算机折扣类
- public class ComputerDiscount implements Discount{
- private float discount=0.0f;
- public float getDiscount(){
- return discount;
- }
- public void setDiscount(float discount){
- this.discount=discount;
- }
- }
// 文具折扣类
- public class StationaryDiscount implements Discount{
- private float discount=0.0f;
- public float getDiscount(){
- return discount;
- }
- public void setDiscount(float discount){
- this.discount=discount;
- }
- }
// 纸张折扣类
- public class PaperDiscount implements Discount{
- private float discount=0.0f;
- public float getDiscount(){
- return discount;
- }
- public void setDiscount(float discount){
- this.discount=discount;
- }
- }
// 其它折扣类
- public class OtherDiscount implements Discount{
- private float discount=0.0f;
- public float getDiscount(){
- return discount;
- }
- public void setDiscount(float discount){
- this.discount=discount;
- }
- }
// 订单类
- public class Order{
- public static final String Type_Computer="Computer";
- public static final String Type_Stationary="Stationary";
- public static final String Type_Paper="Paper";
- private String type;
- private float price;
- public Order(float price,String type){
- this.price=price;
- this.type=type;
- }
- public Order(){
- this(100.0f,"Other");
- }
- // 调用模拟类的地方,看看调用过程和Spring很相似吧
- public float getPrice() {
- MockContext ctx = new MockContext("bean.xml");
- Discount discount = null;
- discount = (Discount) ctx.getBean(this.type);
- return price * (1.0f - discount.getDiscount());
- }
- }
// Spring之FileSystemXmlApplicationContext的模拟类
- /**
- * Spring之FileSystemXmlApplicationContext的模拟类
- *
- * @author junglesong
- *
- */
- public class MockContext {
- Document doc = null;// 用于解析Bean配置文件的Xml Document
- Element root = null;// Bean文件的根节点
- /**
- * 构造函数,用于初始化doc和root
- * @param beanFileName
- */
- public MockContext(String beanFileName) {
- SAXBuilder buider = new SAXBuilder();
- try {
- doc = buider.build(new File(beanFileName));
- root = doc.getRootElement();
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
- /**
- * 根据beanId创建类并调用规定的方法
- *
- * @param beanId
- * @return
- */
- public Object getBean(String beanId) {
- Object obj=null;
- try {
- Element beanElm =getSubElm(root,"id",beanId);
- if(beanElm!=null){
- String className=beanElm.getAttribute("class").getValue();
- Class cls=Class.forName(className);
- // 由类得到类实例
- obj=cls.newInstance();
- List ls=beanElm.getChildren();
- for(Iterator it=ls.iterator();it.hasNext();){
- Element elm=(Element)it.next();
- String methodName=elm.getAttributeValue("name");
- String methodValue=(String)elm.getChildText("value");
- // 取得类方法
- Method method = cls.getMethod(getSetterMethod(methodName), new Class[] {getClassByValue(methodValue)});
- // 建立数组
- Object params[]=getParamsByValue(methodValue);
- // 调用类方法
- method.invoke(obj,params);
- }
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- return obj;
- }
- /**
- * 由参数的值得到参数的类型,目前可处理浮点数和字符串两种情况
- *
- * @param value
- * @return
- */
- private Class getClassByValue(String value){
- Class cls=String.class;
- try{
- Float.parseFloat(value);
- cls=float.class;
- }
- catch(Exception ex){
- ex.printStackTrace();
- }
- return cls;
- }
- /**
- * 由参数的值得到包含参数的数组,目前可处理浮点数和字符串两种情况
- *
- * @param value
- * @return
- */
- private Object[] getParamsByValue(String value){
- Object[] params=new Object[1];
- try{
- Float.parseFloat(value);
- params[0]=new Float(Float.parseFloat(value));
- }
- catch(Exception ex){
- ex.printStackTrace();
- params[0]=new String(value);
- }
- return params;
- }
- /**
- * 取得root下属性为subElmAttr,值等于subElmValue的节点
- *
- * @param root
- * @param subElmAttr
- * @param subElmValue
- * @return
- */
- private Element getSubElm(Element root,String subElmAttr,String subElmValue){
- Element rtv=null;
- List ls=root.getChildren();
- for(Iterator it=ls.iterator();it.hasNext();){
- Element elm=(Element)it.next();
- if(elm.getAttribute(subElmAttr).getValue().equals(subElmValue)){
- rtv=elm;
- break;
- }
- }
- return rtv;
- }
- /**
- * 取得setter方法
- *
- * @param methodName
- * @return
- */
- private String getSetterMethod(String methodName){
- return "set"+methodName.substring(0,1).toUpperCase()+methodName.substring(1,methodName.length());
- }
- }
调用的代码如下:
java 代码
- Order computerOrder=new Order(100.0f,Order.Type_Computer);
- System.out.println("computerOrder's price is \t"+computerOrder.getPrice());
- Order stationaryOrder=new Order(100.0f,Order.Type_Stationary);
- System.out.println("stationaryOrder's price is \t"+stationaryOrder.getPrice());
- Order paperOrder=new Order(100.0f,Order.Type_Paper);
- System.out.println("paperOrder's price is \t\t"+paperOrder.getPrice());
- Order otherOrder=new Order();
- System.out.println("otherOrder's price is \t\t"+otherOrder.getPrice());
输出效果和使用Spring是一样的,速度慢了些,但可以优化:
java 代码
- computerOrder's price is 70.0
- stationaryOrder's price is 80.0
- paperOrder's price is 90.0
- otherOrder's price is 95.0
感悟: 有些关键性的框架要知其然知之其所以然,不能满足于使用.纸上得来终觉浅,绝知此事要躬行.实现完了再看源码也许更有感悟.
相关日志:
收藏:
QQ书签
del.icio.us
订阅:
Google
抓虾
