拙文:Digester3小记

缘起:

之前一段时间在复习以前学习的Digester使用的时候,由于机器上没有备份Digester的相关包,所以就直接去咱们apache的官网上找Digester的包,一般我都喜欢下最新版的jar包,虽然新版本有可能不稳定,但是迫于追求新东西的欲望,我一般会尝试下载最新jar包(当然最新的版本也可能是几年前发布的了)。所以理所当然就下载了Version: 3.3的Digester包。

 

惑起:

既然jar包下载完毕,就立马导入到项目中,期盼着红xx能够快点消失,可是等了一会却没有动静。如下代码的第二行是主要问题,其实我就是个Digester初学者而已,一时兴起来玩下,谁知玩出了火来,把以前的代码玩完了。

URL url = MyOldCode.class.getResource("rule.xml");
Digester digester = DigesterLoader.createDigester(url);

 

原因:

可能会用Digester的朋友见到上面的代码也许会感到陌生或者奇怪,说来也巧、也怪,偏偏我学的时候就是学得这种写法,看来下源代码,DigesterLoader.createDigester内部原本是这么写的:

public static Digester createDigester(URL rulesXml) {
    RuleSet ruleSet = new FromXmlRuleSet(rulesXml);
    Digester digester = new Digester();
    digester.addRuleSet(ruleSet);
    return digester;
}

可见这仅仅是封装了一点点‘繁琐’的代码而已,可是这代码在Digester3中消失不见了……(PS:并不是说以前的代码在Digester3中完全无法使用了,只是说部分少数有些变动了,如关于xml文件读取规则的有些改变了,其他我不怎么了解。)

 

新发现:

苦于对Digester使用的孤陋寡闻,而在网上搜索Digester3的使用无果(因为网上搜到的都是之前版本的使用),因此我只能硬着头皮去其官网上看那些外星文字了,一个个闪闪发亮的,好在现在科技发达了,有高科技能够为我们翻译了。一个个翻译下勉强了解个大概(别指望我翻译了,能讲个大概不错了,当然我也在努力中~)。

终于在http://commons.apache.org/digester/guide/binder.html这发现了Digester3的新特性了,在新版本中引入了RuleModule和RulesBinder。从名字可了解一个是规则模型,一个是规则捆绑者,似乎是用来代替老版本中的RuleSet的概念,当然在Digester3中是兼容RuleSet的大部分使用的。

 

使用对比:

Digester3之前的使用一般是这样的

    try {
      Digester digester = new Digester();
      digester.addObjectCreate("emp", Emp.class);
      digester.addSetProperties("emp");
      digester.addBeanPropertySetter("emp/name");
      digester.addBeanPropertySetter("emp/id");
      Emp emp = (Emp) digester.parse(TestOld.class.getResource("emp.xml"));
      System.out.println(emp);
    } catch (IOException e) {
      e.printStackTrace();
    } catch (SAXException e) {
      e.printStackTrace();
    }

 

如果使用RuleSet的话,如下所示,即在RuleSet中添加规则,如果每次创建一个Digester都需要再次执行一遍

public class EmpRuleSet implements RuleSet {
  //...略
  @Override
  public void addRuleInstances(Digester digester) {
    digester.addObjectCreate("emp", Emp.class);
    digester.addSetProperties("emp");
    digester.addBeanPropertySetter("emp/name");
    digester.addBeanPropertySetter("emp/id");
  }
}
  public static void main(String[] args) {
    try {
      Digester digester = new Digester();
      EmpRuleSet ruleset = new EmpRuleSet();
      ruleset.addRuleInstances(digester);
      Emp emp = (Emp) digester.parse(TestOld.class.getResource("emp.xml"));
      System.out.println(emp);
    } catch (IOException e) {
      e.printStackTrace();
    } catch (SAXException e) {
      e.printStackTrace();
    }
  }

 

而在Digester3中,提供了工厂的方式来创建Digester,即通过DigesterLoader来创建(DigesterLoader在老版本中似乎主要是用来加载xml规则文件用的),通过传入规则模型来生产Digester对象,使用如下,其中AbstractRulesModule是对RulesModule的封装,原本需要通过cinfigure传进的RulesBinder来设置规则,经过封装直接调用相应的方法就可以设置规则了。

public class EmpRuleModule extends AbstractRulesModule {
  @Override
  protected void configure() {
    System.out.println("type");
    //根据具体类创建对象
    forPattern("emp").createObject().ofType(Emp.class);//.then().setProperties();//要一条龙的写法则通过then方法!
    //设置标签上的全部对应属性
    forPattern("emp").setProperties();
    //将子节点set到其父节点
    forPattern("emp/name").setBeanProperty();
    forPattern("emp/id").setBeanProperty();
  }
}
public class FirstTest {
  public static void main(String[] args) {
    try {
      // 1、创建规则模型类,实现config方法来配置解析规则。然后new该实例来使用
      EmpRuleModule empRuleModule = new EmpRuleModule();
      // 2、根据规则模型类,创建解析器的工厂类
      DigesterLoader loader = DigesterLoader.newLoader(empRuleModule);
      // 3、通过工厂类创建解析器
      Digester digester = loader.newDigester();// 同时调用了RuleModule的config方法添加规则
      // 4、解析xml文件
      Emp emp = digester.parse(FirstTest.class.getResource("emp.xml"));// 这里貌似用了泛型了,不需要转型了
      System.out.println(emp);
      Digester digester2 = loader.newDigester();// RuleModule的config不会再被调用了,只解析了一次
    } catch (IOException e) {
      e.printStackTrace();
    } catch (SAXException e) {
      e.printStackTrace();
    }
  }
}

其实该方式的底层还是用了RuleSet,只不过是只是存放了一份,而不是像之前那样每次都创建一份。

 

Over了吧,行吗?

写在结尾,My God,这文章真得好难写啊,毕竟对Digester内部实现不咋了解,写这个还主要是学习和记录下Digester3的使用,很多不足,请看者见谅。

噩梦结束了…… 拜

你可能感兴趣的:(DI)