Struts1源码-关于Digester的SetNextRule的一点想法

来源:互联网 发布:红太阳软件 编辑:程序博客网 时间:2024/05/13 22:25




对于Digester的使用最近才明白一直以来的疑惑,主要是针对SetNextRule的。以下面的部分的xml为例: 
Xml代码  收藏代码
  1. <Server port="8005" shutdown="SHUTDOWN">  
  2.   <Service name="Catalina">  
  3.     <Executor name="tomcatThreadPool" maxThreads="150" minSpareThreads="4">  
  4.     </Executor>  
  5.   </Service>  
  6. </Server>  

其对应的Digester的构造代码大致如下: 
Java代码  收藏代码
  1. Digester digester = new Digester();  
  2.   
  3. digester.push(this);  
  4.   
  5. digester.addObjectCreate("Server","org.apache.catalina.core.StandardServer","className");  
  6. digester.addSetProperties("Server");  
  7. digester.addSetNext("Server","setServer","org.apache.catalina.Server");  
  8.   
  9. digester.addObjectCreate("Server/Service","org.apache.catalina.core.StandardService","className");  
  10. digester.addSetProperties("Server/Service");  
  11. digester.addSetNext("Server/Service","addService","org.apache.catalina.Service");  
  12.   
  13. digester.addObjectCreate("Server/Service/Executor","org.apache.catalina.core.StandardThreadExecutor","className");  
  14. digester.addSetProperties("Server/Service/Executor");  
  15. digester.addSetNext("Server/Service/Executor","addExecutor","org.apache.catalina.Executor");  
  16. ...  

按照API文档,当parse时,过程应该是把this(Catalina)对象压栈,看到addObjectCreate就把StandardServer实例压栈,接着第一次看到了addSetNext时会做什么呢? 

SetNextRule的api说当碰到下一个pattern元素(此例是'server')时,栈顶对象出栈,并把其作为参数按照method传递给top-1的对象,在此处就是把Server的实例通过Catalina的setServer传递调用,当这个方法完毕,Server也就出栈了。关键就是这句'碰到下一个pattern元素',说的不明不白,网上搜了一堆的资料看也基本上直接翻译的,没有过多的解释。如果不管这句话,暂时直接理解成看到SetNextRule就执行出栈,赋值。那么继续看下面的元素,Service的对象又入栈了,当再次看到addSetNext的时候,此时栈顶的Service出栈,并传给addService作为参数,这个addService的方法是Server的,但是Server出栈了,top-1是Catalina,显然不成立。 

那么什么样的流程能解释呢?对应看xml文件,第一次看到Server是<Server>元素的开始,再次看到Server呢,对应的肯定是</Server>结束,这就是所谓的'下一个pattern元素'了,所以此后的过程就非常清晰了。遵循着类似递归的过程,由内而外的执行SetNextRule的匹配规则,Catalina,Server,Service,Executor相继入栈,最先看到下一个pattern元素的是</executor>所以调用Service的addExecutor执行完毕,Executor出栈;接着看到</Service>执行Server的addService,然后Service出栈,随后</Server>执行Catalina的setServer,最后Server出栈。 

简单的理解是所谓的'the next pattern element'一般情况下可以看作tag的结束符。这样理解关于Digester的构造简单而且好辨别。虽然没有去看它的源码,但是个人认为这种推理应该是有一定的道理的。