`
jljlpch
  • 浏览: 323182 次
  • 性别: Icon_minigender_1
  • 来自: 南昌
社区版块
存档分类
最新评论

stripes 的Intercept Execution

阅读更多
上面的我们看到stripes通过配置文件把框架的大部分功能组件组合在一起,组合在一起,那么怎么有序运行呢?同时不能失去框架的扩展性,不能就顺序执行组件吧,现在的流行的框架都是采用IOC容器来组合这些组件,像structs2采用xwork IOC容器,tapestry5现在采用spring IOC容器。IOC(控制反转)实际上就是拦截器。在servlet Filter中,我们应该知道什么是拦截器吧。Stripes是框架,不能没有扩展性,但stripes又不想弄得太复杂。没有像别的框架借助于别的IOC容器。Stripes实现了一个小的拦截器子系统,6LifecycleStage拦截器子系统中执行,同时,stripes又给用户实现拦截器的接口,通过配置,可以在自己的系统中实现功能强大的拦截功能。

Interceptor.java

 public interface Interceptor {
    Resolution intercept(ExecutionContext context) throws Exception;}

 

上面的Interceptor接口的代码,我们可以看出它使用了ExecutionContext,什么是ExecutionContext就是整个stripes执行时上下文,也就是说在stripes框架在执行时,只要调用这个上下文,就可以得整个生命周斯所需要的东西。
ExecutionContext.java
public class ExecutionContext {
    private static final Log log = Log.getInstance(ExecutionContext.class);

    private Collection<Interceptor> interceptors;
    private Iterator<Interceptor> iterator;
    private Interceptor target;
    private ActionBeanContext actionBeanContext;
    private ActionBean actionBean;
    private Method handler;
    private Resolution resolution;
    private LifecycleStage lifecycleStage;

    。。。。。
    public Resolution wrap(Interceptor target) throws Exception {
        this.target = target;
        this.iterator = null;
        return proceed();
    }    
    public Resolution proceed() throws Exception {
        if (this.iterator == null) {
            log.debug("Transitioning to lifecycle stage ", lifecycleStage);
            this.iterator = this.interceptors.iterator();
        }
        if (this.iterator.hasNext()) {
            return this.iterator.next().intercept(this);
        }
        else {
            return this.target.intercept(this);
        }
    }
}

 

省去了set,get方法,ExecutionContext就只有两个功能方法。proceed()方法就像servlet filterproceed()filterChain.doFilter(request, response);运行接下来的过滤器一样,运行下一个拦截器。,ExecutionContext8个属性。Interceptors是指本生命周期阶段的所有要执行的Interceptoriterator是指Interceptors集合中某一个,因为采用iterator,所以Interceptor集合中的Interceptor执行是不保证顺序的。也就是说同一个阶段的拦截器不能形成依赖关系。Target是目标Interceptor,每一个阶段都一定执行的InterceptorResolution是解析器,就像structsActionForward一样。lifecycleStage就是前面讲的6个生命阶段。 我们可以找一个例子:
DispatcherHelper.java
public static Resolution resolveHandler (final ExecutionContext ctx) throws Exception {
        final Configuration config = StripesFilter.getConfiguration();
        ctx.setLifecycleStage(LifecycleStage.HandlerResolution);
        ctx.setInterceptors(config.getInterceptors(LifecycleStage.HandlerResolution));

        return ctx.wrap( new Interceptor() {
            public Resolution intercept(ExecutionContext ctx) throws Exception {
                ActionBean bean = ctx.getActionBean();
                ActionBeanContext context = ctx.getActionBeanContext();
                ActionResolver resolver = config.getActionResolver();

                // Then lookup the event name and handler method etc.
                String eventName = resolver.getEventName(bean.getClass(), context);
                context.setEventName(eventName);

                final Method handler;
                if (eventName != null) {
                    handler = resolver.getHandler(bean.getClass(), eventName);
                }
                else {
                    handler = resolver.getDefaultHandler(bean.getClass());
                    if (handler != null) {
                        context.setEventName(resolver.getHandledEvent(handler));
                    }
                }

                // Insist that we have a handler
                if (handler == null) {
                    throw new StripesServletException(
                            "No handler method found for request with  ActionBean [" +
                            bean.getClass().getName() + "] and eventName [ " + eventName + "]");
                }

                log.debug("Resolved event: ", context.getEventName(), "; will invoke: ",
                          bean.getClass().getSimpleName(), ".", handler.getName(), "()");

                ctx.setHandler(handler);
                return null;
            }
        });
    }

 

这个方面是在生命周期的第二个阶段执行。首先给ExecutionContext设定了所处的阶段,接着去找这个阶段的Interceptors.怎么找呢?它调用了DefaultConfiguration.java

 
public Collection<Interceptor> getInterceptors(LifecycleStage stage) {
        Collection<Interceptor> interceptors = this.interceptors.get(stage);
        if (interceptors == null) {
            interceptors = Collections.emptyList();
        }
        return interceptors;
}

 

方法。在这个方法从本实现的所有interceptors取到属性本阶段的。Interceptors是在DefaultConfigurationinit()方法中:
this.interceptors = initInterceptors();
            if (this.interceptors == null) {
                this.interceptors = new HashMap<LifecycleStage, Collection<Interceptor>>();
                Class<? extends Interceptor> bam = BeforeAfterMethodInterceptor.class;
                BeforeAfterMethodInterceptor interceptor = new BeforeAfterMethodInterceptor();
                for (LifecycleStage stage : bam.getAnnotation(Intercepts.class).value()) {
                    Collection<Interceptor> instances = new ArrayList<Interceptor>();
                    instances.add(interceptor);
                    this.interceptors.put(stage, instances);
                }

 

还记得前面讲过DefaultConfiguration是模版类吗?initInterceptors()在本类是默认的return null实现,推迟到子类实现。看看RuntimeConfiguration.java@Override 
protected Map<LifecycleStage, Collection<Interceptor>> initInterceptors() {
        String classList = getBootstrapPropertyResolver().getProperty(INTERCEPTOR_LIST);
        if (classList == null) {
            return null;
        }
        else {
            String[] classNames = StringUtil.standardSplit(classList);
            Map<LifecycleStage, Collection<Interceptor>> map =
                    new HashMap<LifecycleStage, Collection<Interceptor>>();

            for (String className : classNames) {
                try {
                    Class<? extends Interceptor> type = ReflectUtil.findClass(className.trim());
                    Intercepts intercepts = type.getAnnotation(Intercepts.class);
                    if (intercepts == null) {
                        log.error("An interceptor of type ", type.getName(), " was configured ",
                                  "but was not marked with an @Intercepts annotation. As a ",
                                  "result it is not possible to determine at which ",
                                  "lifecycle stages the interceprot should be applied. This ",
                                  "interceptor will be ignored.");
                    }
                    else {
                        log.debug("Configuring interceptor '", type.getSimpleName(),
                                  "', for lifecycle stages: ", intercepts.value());
                    }

                    // Instantiate it and optionally call init() if the interceptor
                    // implements ConfigurableComponent
                    Interceptor interceptor = type.newInstance();
                    if (interceptor instanceof ConfigurableComponent) {
                        ((ConfigurableComponent) interceptor).init(this);
                    }

                    for (LifecycleStage stage : intercepts.value()) {
                        Collection<Interceptor> stack = map.get(stage);
                        if (stack == null) {
                            stack = new LinkedList<Interceptor>();
                            map.put(stage, stack);
                        }

                        stack.add(interceptor);
                    }
                }
                catch (Exception e) {
                    throw new StripesRuntimeException(
                            "Could not instantiate one or more configured Interceptors. The " +
                            "property '" + INTERCEPTOR_LIST + "' contained [" + classList +
                            "]. This value must contain fully qualified class names separated " +
                            "by commas.", e);
                }
            }

            return map;
        }
}

 

这个方法取到配置中的拦截器s,并实例化它们,之后按生命周期分成6类放在renturn中的Map<LifecycleStage, Collection<Interceptor>>中。现在回到resolveHandler方法,这个方法接下来就是return ctx.wrap( new Interceptor() {..});这个实现了一个匿名的Interceptor,之后执行ExcuteContext.wrap(Interceptor)方法。还记得wrapinterceptor,它是一个包扎方法,把这个匿名Interceptor保存ExcuteContext   target对象。this.target = target;接下的这句 this.iterator = null;仅仅是代码的实现技巧,这个是要在下面的 return proceed();做判断处理。

 
public Resolution proceed() throws Exception {
        if (this.iterator == null) {
         log.debug("Transitioning to lifecycle stage ", lifecycleStage);
            this.iterator = this.interceptors.iterator();        }
        if (this.iterator.hasNext()) {
            return this.iterator.next().intercept(this);        }
        else {      return this.target.intercept(this);       }    }
 

 

this.iterator = null的作用仅仅是为了找到这一阶段的interceptors。如果找到了就是执行这一阶段的interceptors中的iterator。在这里看到,每一个阶段只能执行一个interceptors的第一个。那剩下的呢怎么办?剩下就是用户实现的拦截器的传递了。如果用户的实现的拦截器没用传递。那之后就不执行,连本阶段的匿名Interceptor都不会执行就直接返回。返回的是Resolution不为null,那个整个流程就结束,剩下的执行Resolution的跳起页面功能(像structs ActionForward,比它的功能强)。用户实现的拦截如下:
@Intercepts({LifecycleStage.ActionBeanResolution})
public class HibernateInterceptor implements Interceptor
{	private static Log log = Log.getInstance(HibernateInterceptor.class);private boolean initializedHibernateProvider = false;
public Resolution intercept(ExecutionContext context) throws Exception
	{log.debug("HibernateInterceptor called");
if (!initializedHibernateProvider && (HibernateProvider.getInstance() == null) && (HibernateFilter.getCurrentInstance() != null))
		{log.info("Initializing HibernateProvider");
HibernateProvider.setInstance(HibernateFilter.getCurrentInstance());
			initializedHibernateProvider = true;		}
		return context.proceed();	}
看到最后一句的:return context.proceed();从现在开始iterator都不为空。那么就找下一个Interceptor,没有的话,就执行本阶段的目标this.target.intercept(this);这个是在本阶段最后执行的。
如果用户采用如下的话:
@Intercepts({LifecycleStage.HandlerResolution})
public class NoisyInterceptor implements Interceptor {
public Resolution intercept(ExecutionContext ctx) throws Exception {
System.out.println("Before " + ctx.getLifecycleStage());
Resolution resolution = ctx.proceed();
System.out.println("After " + ctx.getLifecycleStage());
return resolution}}

 

那就是一个嵌套的执行,最后还会返回来执行Resolution resolution = ctx.proceed();下面的语句。ctx.proceed()上面的语句是在目标Interceptor之前执行。下面的语句是在目标Interceptor之后执行。Stripes有一个默认的@before@after就是一个在前面一个后面的实现。分析完了,是不是自己也想写一个interceptor。写interceptor很简单,只要实现implements Interceptor,也就是实现了public Resolution intercept(ExecutionContext ctx) throws Exception就可以。还有一点不能忘记,这个interceptor是在那个阶段执行的,@Intercepts({LifecycleStage.HandlerResolution})就是在HandlerResolution执行。 
分享到:
评论

相关推荐

    Stripes视图框架demo

    Stripes视图框架是一款轻量级的Java Web框架,它为开发者提供了构建高效、可维护的Web应用程序的工具。这个“Stripes视图框架demo”是用于演示如何使用Stripes来开发Web应用的一个实例,可以帮助初学者快速理解和...

    stripes英文文档(全部)

    Stripes 是一款用于快速开发Web程序的展示层框架,它的设计旨在简化Java Web应用开发流程。在介绍Stripes之前,我们需要了解它与传统框架(如 Struts 1、WebWork 和 Struts 2)的不同之处。传统框架通常要求开发者...

    stripes 和css 一些常用功能

    Stripes是一个Java Web应用框架,它是为了简化Java Web开发而设计的,提供了快速构建Web应用程序的能力。与传统的框架如Struts1和Struts2相比,Stripes有自己独特的优势。首先,Stripes提倡“约定优于配置”的开发...

    stripes入门

    ### Stripes 入门 Stripes 是一款专为简化 Java Web 开发流程而设计的开源框架,它以提高开发效率为目标,力求使开发者能够轻松快速地构建 Web 应用程序。与传统 Java Web 框架相比,Stripes 采用了更为简洁的方法...

    Folio图书馆系统UI前端框架stripes-components-master

    《Folio图书馆系统UI前端框架Stripes-Components详解》 在现代数字图书馆系统中,用户界面(UI)的设计与实现是至关重要的,它直接影响到用户的使用体验和系统的易用性。Folio图书馆系统是一个开放源代码的平台,...

    在Stripes中下载excel表格

    ### 在Stripes中实现Excel表格下载的关键技术点 #### 一、Stripes框架简介 Stripes是一个基于Java的Web应用开发框架,它采用MVC(Model-View-Controller)架构模式设计,旨在简化Web应用程序的开发流程。相较于...

    Stripes 快速入门 pdf 中文版 下载

    ### Stripes框架简介 #### 1.1. 初识Stripes Stripes是一个轻量级的Java Web应用框架,其设计目标是简化Java web应用的开发过程,并提高开发效率。与Struts 1和Struts 2等早期流行的框架不同,Stripes采用了更为...

    stripes快速入门教程

    不错的stripes教程,分享一下…… 和我们熟悉 Struts 1 和 Struts 2 类似,Stripes 同样是一种展示层框架,用于快速构建web程序。在使 用Struts 1,WebWork 和 Struts 2 等框架的时候,通常需要大量额外的 XML 配置...

    轻量级mvc框架之:stripes (一、约定大于配置)

    Stripes是一个轻量级的Java MVC框架,它的核心设计理念是“约定大于配置”,这使得开发者可以更快地构建Web应用程序,而无需过多的配置文件。在本文中,我们将深入探讨Stripes框架的基础知识,以及它如何简化开发...

    stripes+spring+mybatis框架

    stripes1.5.7+spring3.1.1+MyBatis3.1.1完整框架 本工程代码已完成了Oracle,MySQL,MSSQL2005三种数据库物理分页方言,并测试可用。 本代码集成了xheditor-1.2.1在线编辑器远程抓取图片功能。 集成了excel导入...

    jsp网页布局利器框架stripes-1.5.6

    Stripes是一个基于Java的轻量级MVC(Model-View-Controller)框架,它专注于简化Web应用程序的开发。在标题“jsp网页布局利器框架stripes-1.5.6”中,提到的“jsp”指的是JavaServer Pages,一种用于创建动态网页的...

    Stripes1.4.3

    Stripes是一个专为简化Java Web开发而设计的开源框架,其版本1.4.3是该框架的一个稳定发行版。这个框架强调了提高程序员的工作效率和代码的可维护性,通过提供直观的API和强大的特性集,使得构建动态、交互式的Web...

    stripes mvc pdf

    ### Stripes MVC Framework:概述与核心特性 #### 一、Stripes框架简介 Stripes是一款新兴的Java Web MVC(Model-View-Controller)框架,它以其简洁、高效和易用的特点受到开发者的青睐。该框架的目标是简化Java ...

    stripes-1.5.7-src.zip

    Stripes是一个轻量级的Java Web框架,它简化了创建动态、交互式的Web应用程序的过程。这个"stripes-1.5.7-src.zip"文件包含了Stripes框架的源代码版本1.5.7,这对于开发者来说是宝贵的资源,因为可以直接查看和理解...

    Stripes使用Ajax

    ### Stripes框架与Ajax结合应用详解 #### 一、Stripes框架简介 Stripes是一个用于Java Web开发的轻量级框架,它旨在简化MVC(Model-View-Controller)架构的应用程序开发过程。与Struts2相比,Stripes更加简洁明了...

    stripes包,内有例子程序和StripesResources.properties

    Stripes是一个轻量级的Java Web框架,它简化了创建动态、交互式的Web应用程序的过程。这个压缩包"stripes-1.5.6"包含了Stripes框架的一个版本以及相关的示例程序和配置文件,这对于学习和理解Stripes的工作原理非常...

    基于Stripes框架的Ajax应用与研究.pdf

    基于Stripes框架的Ajax应用与研究 本文主要研究了基于Stripes框架的Ajax应用,旨在提高Web 2.0网站的用户体验和数据传输速度。文章首先介绍了Web 2.0时代的到来和Ajax技术在其中的重要作用,然后对Stripes框架进行...

Global site tag (gtag.js) - Google Analytics