1.概述
pull service的功能是将对象置入模板中。被pull service放到模板中的对象,不需要应用程序的干预即可直接使用。如果模板没有用到某个对象,则不会产生创建该对象的开销。看起来,这些对象像是被模板主动“拉”进context的,而不是由应用程序push进context中的。这就是pull service名称的来源。
2.作用域
global :就是singleton,在系统启动时创建实例。
request :在每个request的第一次访问该tool时,自动创建实例。
注意,!ToolFactory和ToolSetFactory本身一定是singleton的。但他们所创建的tool对象的作用域,是由ToolFactory或ToolSetFactory.isSingleton方法决定的。
3.全局性
parent context中的tools被所有子context中的tools共享。但子context可以覆盖父context中的同名tools(注:只是以当前context的tool的引用为优先,不影响父context中的实例)。
4.使用
<services:pull xmlns="http://www.alibaba.com/schema/services/pull/factories">
< … />
/services:pull>
5.ID命令约定
<tool id="xxx">,(明确指定)此时id=xxx
<tool class="com....!HelloTool>,此时id=hello
<tool class="com....Hello>,此时id=hello
<hello-tool > 此时id=hello
6.共享实例
如果每个sub context中分别配置pull service,那么即使同名的tool,在内存中也是两份实例。
如果希望多个sub context中共享一个实例,就把它定义在parent context中。
7.使用方法
package com.alibaba.webx.tutorial1.app1.tool; import java.text.SimpleDateFormat; import java.util.Date; public class MyPullTool{ public static String method1(){ return "hello, xiao xiong!"; } public String method2(Date date){ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String new_date = format.format(date); return new_date; } }
在webx.xml配置
<services:pull xmlns="http://www.alibaba.com/schema/services/pull/factories"> <utils /> <page-tool /> <control-tool /> <uris-tool /> <bean-tool id="mytool" class="com.alibaba.webx.tutorial1.app1.tool.MyPullTool" scope="global" autowire="true"/> </services:pull>
在vm中使用方式
$rundata.response.setContentType("text/html") $rundata.setLayoutEnabled(false) <p>Welcome!</p> 今天是 $mytool.method2($date)
优势:使用bean-tool
1你可以方便的将已有的一个工具类配置一下就可以变成PullTool而不需要专门实现任何接口、去除了对原有类的不必要侵入,
2可以将Spring容器的一个Bean作为PullTool使用
8.扩展
8.1.1 创建新的tool factory
public class MyToolFactory implements ToolFactory { private boolean singleton = true; private DomTool tool; public void setSingleton(boolean singleton) { this.singleton = singleton; } public Object createTool() throws Exception { if (this.singleton) { if (tool == null) { tool = new DomTool(); } return tool; } else { return new DomTool(); } } public boolean isSingleton() { return this.singleton; } }
public class DomTool { public void addScript(String scriptURI) { } public void addCss(String cssURI) { } }
8.1.2 配置
<factory id="domTool" class="com.alibaba.sample.showcase.commons.pull.MyToolFactory" p:singleton="true" />
8.1.3 模板中使用
$domTool.addScript("scripts/test.js");
8.2.1 实现ToolSetFactory
public class MyToolSetFactory implements ToolSetFactory { private boolean singleton = true; Map<String, Object> tools = new ConcurrentHashMap<String, Object>(); public MyToolSetFactory() { tools.put("toolA", new ToolA()); tools.put("toolB", new ToolB()); } public void setSingleton(boolean singleton) { this.singleton = singleton; } public Object createTool(String name) throws Exception { Object tool = null; if (this.singleton) { tool = tools.get(name); } else { tool = this.makeTool(name); } if (tool == null) { throw new RuntimeException("tool '" + name + "' is not found"); } return tool; } public Iterable<String> getToolNames() { return this.tools.keySet(); } public boolean isSingleton() { return this.singleton; } private Object makeTool(String name) { if ("toolA".equals(name)) { return new ToolA(); } else if ("toolB".equals(name)) { return new ToolB(); } return null; } }
8.2.2 配置
<factory id="myToolSet" class="com.alibaba.sample.showcase.commons.pull.MyToolSetFactory" p:singleton="true" />
8.2.3 使用
$toolA.say("hello toolA") $toolB.sing("happy birthday")