Cubby的plugin的实现原理以及执行顺序分析

在cubby里可以使用plugin实现拦截器。通常的做法是重载plugin的invokeAction方法对Action方法进行拦截。

执行顺序

CubbyFilter  -->  Action.initialize() --> Plugin.invokeAction() --> Actoin.xxx() 


plugin代码示例

public class TestPlugin extends AbstractPlugin {

@Override
public ActionResult invokeAction(final ActionInvocation invocation)
throws Exception {

//Action前的处理
......

//Action处理xxxAction action = (xxxAction) invocation.getActionContext().getAction();
ActionResult result = super.invokeAction(invocation);

//Action后的处理
...... 

return result;
}
}




Plugin的加载方式和执行顺序创建的plugin需要把完整的类路径写到一个叫“org.seasar.cubby.plugin.Plugin”的文本文件里,文件位置在“"META-INF/services/”下。如:
com.example.plugin.TestPlugin
这里的文件名和文件位置是固定的。可以查看Cubby源代码的plugin加载类:
org.seasar.cubby.internal.util.ServiceLoader
这个类里的代码
private static final String PREFIX = "META-INF/services/";
决定了文件的位置。
而通过这个类里的代码
final String resourceName = PREFIX + service.getName();
可以发觉文件名就是从plugin管理类
org.seasar.cubby.internal.plugin.PluginManager
的代码
for (final Plugin plugin : ServiceLoader.load(Plugin.class)) {
plugins.add(plugin);
}
传递过来的Plugin.class的完整类名,即org.seasar.cubby.plugin.Plugin。
所以,这个文件的名字和位置是有框架的源代码决定的固定值。

另外,通过源代码可以发现,在ServiceLoader类中,加载的plugin是存储在LinkedHashMap<String, S>中的,因此这时候是有序的。

而在返回到类PluginManager时,plugin是存储在LinkedHashSet<Plugin>中的,因此,到这里为止plugin还是有序的。
但是,PluginManager里把plugin加载到类PluginRegistry中的时候,是存储在HashSet<Plugin>里的,所以最后又变成无序的了。
而执行plugin的代码是在类ActionProcessorImpl中以下代码取得类PluginRegistry里的plugin的迭代器,
this.pluginsIterator = pluginRegistry.getPlugins().iterator();
也就是说最终执行plugin时是无序的。

所以,如果需要有序的多个拦截器的话,不要用创建多个plugin的方法。
可以在一个plugin里调用多个类来处理;
也可以把一些前面的处理放到Action的initialize()里 。









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值