ZK工作原理启动篇(二)WebManager的职责
其实在ZK的早期版本中是没有WebManager这个类的,它负责的功能都在DHtmlLayoutServlet中,后来许是开发者觉得这样DHtmlLayoutServlet的责任就太重了,所以按照每个类只做一件事情的思想把有些功能转移到了WebManager中,这也使得ZK软件本身的层次更加清晰。正如ZK文档中所描述的WebManager是Web服务器和ZK之间的桥梁,每一个使用zk的web应用程序都有一个独立且唯一的WebManager实例。WebManager初始化(通过构造方法)WebManager(ServletContext ctx, String updateURI){……}主要完成以下工作:
第一、从metainfo/zk/config.xml(位于ZK的发行包中)和WEB-INF/zk.xml中加载配置,config.xml的源码如下
<?xml version="1.0" encoding="UTF-8"?><config><config-name>zk</config-name><!-- used to resolve dependency --><version><version-class>org.zkoss.zk.Version</version-class><version-uid>3.5.0</version-uid></version><!-- Note: zscript-config is applied to the whole system. Not just this language.--><zscript-config><language-name>Java</language-name><interpreter-class>org.zkoss.zk.scripting.bsh.BSHInterpreter</interpreter-class></zscript-config><device-config><device-type>ajax</device-type><device-class>org.zkoss.zk.device.AjaxDevice</device-class><unavailable-message><!]></unavailable-message></device-config></config>它配置的信息包括版本、脚本语言解释器以及设备,可以看出Java是zk默认的脚本语言,除此之外通过引入解释器这一概念,zk还支持Javascript、Groovy及Ruby语言等,在此不做详细介绍;Device描述了客户端的设备类型,其中使用Ajax的HTML浏览器被称作AjaxDevice,XML输出被称作org.zkoss.zml.device.XmlDevice。
第二、往Labels中注册一个新的LabelLocator并设置变量解析器为ServletLabelResovler。
Labels.register(new ServletLabelLocator(_ctx));Labels.setVariableResolver(new ServletLabelResovler())其中,VariableResolver用于指定表达式(org.zkoss.xel.Expression)在计算时解析变量引用的方式;Labels是用于访问标签(Label)的帮助类,一个Label就是一个与Local有关的字符串,被存放在类似i3-label*.properties的文件中,一旦一个LabelLocator被注册到Labels中,LabelLoader就会通过调用locate(java.util.Locale)去定位任何额外的资源,例如下面是ServletLabelLocator中的部分源码:
//-- LabelLocator --//public URL locate(Locale locale) throws IOException {return _ctx.getResource("/WEB-INF/"+getI3LabelName(locale));}/** Returns the filename of i3-label.properties. */private static final String getI3LabelName(Locale locale) {return locale.equals(Locale.ENGLISH) ?"i3-label.properties": "i3-label_" + locale + ".properties";}可以看出ServletLabelLocator主要用于加载WEB-INF/下所有与i3-label相关的property属性文件,
和我们一般的本地化策略有所不同,假如属性文件中的信息是中文这里没必要通过native2ascii命令将中文转换为ascii码,例如下面分别是zkdemo中WEB-INF/下i3-label.properties与i3-label_zh_CN.properties的源码
#--------------------## Label for zkdemo ##--------------------#username=Usernamepassword=Password
#--------------------## Label for zkdemo ##--------------------#username=用户password=密码第三、创建一个WebApp实例(默认为org.zkoss.zk.ui.http.SimpleWebApp)并初始化
((WebAppCtrl)_wapp).init(_ctx, config);第四、初始化ClassWebResource并加载适当的Extendlet(作为ClassWebResource的插件用于处理特殊的内容)。
_cwr = ClassWebResource.getInstance(_ctx, _updateURI);_cwr.setCompress(new String[] {"js", "css", "html", "xml"});_ctx.setAttribute(ATTR_WEB_MANAGER, this);_cwr.setDebugJS(config.isDebugJS());//Register resource processors for each extension//FUTURE: Extendlet can be specified in zk.xml//Note: getAll loads config.xml, which must be processed before zk.xmlZumlExtendlet extlet = null;for (Iterator it = LanguageDefinition.getAll().iterator();it.hasNext();) {final LanguageDefinition langdef = (LanguageDefinition)it.next();final List exts = langdef.getExtensions();if (!exts.isEmpty()) {if (extlet == null)extlet = new ZumlExtendlet();_cwr.addExtendlet((String)exts.get(0), extlet);//Add to the first extension only (the main one)}}第五、删除所有与ServletContext相关的WebManagerActivationListener并对要删除的每个WebManagerActivationListener调用didActivate(WebManager webman)方法。
((WebManagerActivationListener)it.next()).didActivate(this);附:WebManager所持有重要私有属性
/** Map(ServletContext, List(WebManagerActivationListener)). */private static final Map _actListeners = new HashMap();private final ServletContext _ctx;private final WebApp _wapp;private final String _updateURI;private final ClassWebResource _cwr;
页:
[1]