XWork是一个通用的Command模式框架,对它的关注始于我对Interceptor结构了解的需要。对于起步而言,Hello World级的东西总是最为快捷的选择。 在XWork中,Action用以处理核心的逻辑,下面就是一个: HelloAction.java
java 代码
- import com.opensymphony.xwork.Action;
-
- public class HelloAction implements Action {
- public String execute() throws Exception {
- System.out.println("Hello, World");
- return SUCCESS;
- }
- }
然后是调用这个Action,如果直接调用的话,一来代码显得没有多大意义,二来后面的戏就没法继续了。于是写出这样的代码: Main.java
java 代码
- import com.opensymphony.xwork.ActionProxyFactory;
- import com.opensymphony.xwork.ActionProxy;
-
- public class Main {
- public static void main(String[] args) throws Exception {
- ActionProxyFactory factory = ActionProxyFactory.getFactory();
- ActionProxy proxy = factory.createActionProxy("", "hello", null);
- proxy.execute();
- }
- }
-
AcionProxy,我们可以将它看作Action的一个壳,它的调用最终会作用在Action身上,因此它拥有了“proxy”的美名。而ActionProxyFactory,名字就体现出了它的作用,制造AcitonProxy。 先别忙着运行程序,智慧如你一定会想到,这个proxy怎么和前面的HelloAction关联在一起。我们还需要一个配置文件: xwork.xml
- "http://www.opensymphony.com/xwork/xwork-1.0.dtd">
- <xwork>
- <package name="default">
- <action name="hello" class="HelloAction">
- action>
- package>
- xwork>
“Hello”,这样一个字符串起到“一桥飞架南北,天堑变通途”的作用,一端它在ActionProxyFactory创建ActionProxy时,作为传入参数连接起proxy,另一端它在配置文件中,与具体类型相连,找到了具体的Action。 既然困难已经排除,还等什么?就这样,“Hello, World”出现了。也许会有些无关大雅的警告,说明我们没有为HelloAction返回success进行处理,忽略它。 blog的标题提醒我,终极目标是Interceptor。Interceptor是这样一种架构模式,它允许将服务透明地添加到框架之中,当我们关注的事件发生时,就会自动触发这个服务。JBoss之所以灵活,其核心架构就是Interceptor。对了,XWork的来源于WebWork,而WebWork的创造者便是大名鼎鼎的Rickard Oberg,而他正是JBoss灵活的架构正是出自他的手笔。J2EE开发者的工具箱中还有一件工具也采用了Interceptor的实现,它便是Servlet Filter。了解Interceptor对于理解AOP有着相当的好处,因为二者之间存在太多的相似,以致于有人专门站出来声明“AOP != Interceptor”。 对于程序员而言,任何话语都没有代码来得实惠,下面就是一个Interceptor: HelloInterceptor.java
java 代码
- import com.opensymphony.xwork.interceptor.Interceptor;
- import com.opensymphony.xwork.ActionInvocation;
-
- public class HelloInterceptor implements Interceptor {
- public void init() {
- }
-
- public void destroy() {
- }
-
- public String intercept(ActionInvocation invocation) throws Exception {
- System.out.println("Hello, Interceptor");
-
- return invocation.invoke();
- }
- }
省略用以管理声明周期的init和destroy,我们把焦点放在intercept方法。除了一句将用以证明它存在的打印语句之外,这个方法中还有一条语句:
java 代码
- return invocation.invoke();
在通常的Interceptor实现中,各个Interceptor往往会形成一条链,这句invocation.invoke()就是把控制权交出的方式,调用便是沿着这条链一步步向后面走去,熟悉设计模式的朋友一眼便能看出,这是职责链的一种实现,而它恰恰是Interceptor架构的关键。 为了让它发光发热,我们还需要在配置文件里做一些修改,先是加上一个Interceptor:
xml 代码
- <interceptors>
- <interceptor name="helloInterceptor" class="HelloInterceptor"/>
- interceptors>
接着,要让action知道它的存在,我们还要修改Action:
xml 代码
- <action name="hello" class="HelloAction">
- <interceptor-ref name="helloInterceptor"/>
- action>
至于主文件,就不再修改了,否则如何体现“透明”的添加服务呢! 再次运行程序,劳动成果得到了体现: Hello, Interceptor Hello, World |