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

来源:互联网 发布:小火柴软件 编辑:程序博客网 时间:2024/05/08 13:05

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

执行顺序

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


plugin代码示例

public class TestPlugin extends AbstractPlugin {@Overridepublic 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()里 。









原创粉丝点击