在公司使用pandoraboot配置了velocity tool,一直不明白官方支持的init方法没有调用,而且不支持velocity tool 1.x版本的定义(1.x和2.x的定义见下面),而另一种没使用pandoraboot的源码,确好好的,百思不得其解,然后各种断点调试了一天,发现了端倪,我们的starter中重写了VelocityLayoutView.java类,在new Tool的时候,使用了BeanUtils.instantiate方法,然后导致velocity tool初始化时的各种特性丢失,然后顺带lou了一把Velocity tool的源码,这里抛个砖。
velocity tool定义 1.x定义 <toolbox> <tool> <key>tool</key> <scope>request</scope> <class>org.apache.velocity.tools.generic.AlternatorTool</class> </tool> </toolbox> 2.x定义,key定义在类里面,使用DefaultKey注解的形式 <tools> <toolbox scope="application"> <tool class="org.apache.velocity.tools.generic.AlternatorTool"/> </toolbox> </tools>
Velocity tool的使用方法就不贴了,不懂的自行百度,使用velocity离不开VelocityViewResolver,这个是velocity的根基,首先VelocityViewResolver继承自AbstractTemplateViewResolver,实现了ApplicationContextAware接口,所以在VelocityViewResolver被spring初始化的时候,会调用initApplicationContext方法,这里会设置viewClass,即VelocityToolboxView,
然后控制权会回到DispatcherServlet的render方法中,执行resolveViewName,对应的是调用VelocityViewResolver.buildView,在父类里会调用spring方法BeanUtils.instantiateClass生成一个VelocityToolboxView(这个viewClass就是前面在VelocityViewResolver中设置的),同时调用setToolboxConfigLocation(),这个方法执行完成,VelocityViewResolver的工作就完成了,到这里,我们才有了一个真正的view对象,render方法中继续向前,就会到VelocityToolboxView中的createVelocityContext(),这里会调用ServletToolboxManager.getInstance()方法,这个方法很重要,首先它新建一个会调用ServletToolboxManager,同时这个方法里面加载了toolbox.xml文件并解析(解析是在toolboxManager.load方法里面,不展开了),load完成之后,各个tool类就被加载到ServletToolboxManager对象中了,注意这里tool类还没有被实例化,
最后会调用getToolbox()方法,这个方法里面会实例化各个tool(实例化的时候作了兼容,也就是会调用老1.x tool中的init方法,和2.x tool中configure(Map)),并放到sessionToolInfo和requestToolInfo中
然后流程到这里就完了,有时间补下流程图,睡觉了。