Struts2笔记(10)——拦截器(Interceptor)(一)

拦截器(interceptor)用于AOP编程中某个字段或者方法访问前以及被访问后加入某些操作,拦截是AOP的一种实现策略。拦截器的使用还有一个重要的概念,就是拦截器链(InterceptorChain),意味着被使用的拦截器将会按照一定的顺序形成一条链,在访问被拦截的方法或者字段时就会被顺序调用。

拦截器的实现原理


拦截器大多是通过代理方式实现,Struts2的实现方式相对较为简单。当请求Struts2的StrutsPrepareAndExcuteFilter,也就是我们的前端控制器,前端控制器会访问配置文件,根据配置实例化所需的拦截器,并将拦截器对象放入一个列表,最后依次调用拦截器。Struts2的拦截器是可插拔的。

自定义拦截器的实现

1.实现com.opensymphony.xwork2.interceptor.Interceptor接口,该接口有三个方法:
+ init():初始化方法,在拦截器被创建之时被调用,在Interceptor的生命周期中只会被调用一次,该方法内可以进行相关资源的初始化;
+ intercept(ActionInvocation invocation):拦截器的核心方法,它返回一个字符串作为逻辑视图,系统根据其返回的字符串跳转到相应的视图资源。每拦截一次动作请求,该方法就被执行一次。该方法的ActionInvocation参数包含了被拦截的action的引用,通过该参数的invoke方法,将控制权交给下一个拦截器或者Action的excute方法
+ destroy():销毁方法,用来释放该拦截器相关的资源。在Interceptor的生命周期内同样只被执行一次。

它的生命周期与项目是一致的。(Servlet是在第一次访问时创建,随着项目的关闭而销毁。)
2. 继承AbstractInterceptor类,该类为抽象类,查看其源码,该类实现了Interceptor接口。这样就不需要实现不必要的初始化和销毁方法。
3. 继承MethodFilterInterceptor类,该类能够指定拦截器拦截的方法,以及不需被拦截的方法。

Struts2拦截器链的形成

拦截器的核心拦截方法的传入参数是ActionIvocation,它是一个抽象接口,在DefaultActionInvocation实现的invoke方法中,会判断其

//interceptors是一个拦截器列表
//判断该列表是否调用结束
if (this.interceptors.hasNext()) {
                InterceptorMapping interceptor = (InterceptorMapping)this.interceptors.next();
                String interceptorMsg = "interceptor: " + interceptor.getName();
                UtilTimerStack.push(interceptorMsg);
//没有执行结束,则继续调用下一个拦截器
                try {
                    this.resultCode = interceptor.getInterceptor().intercept(this);
                } finally {
                    UtilTimerStack.pop(interceptorMsg);
                }
            } else {
            //执行结束,反射方式执行action
            //resultCode是Action的执行结果
                this.resultCode = this.invokeActionOnly();
            }

而在所有的预置的Interceptor内的intercept方法内,都有如下源码:

public String intercept(ActionInvocation invocation) throws Exception {
                            ...
                            ...
                            ...
                   return invocation.invoke();
    }

这使得拦截器与invocation之间相互调用形成了类似于循环的作用,最终能够确保将List中的Interceptor执行完毕。
因此,将拦截方法内容置于invocation.invoke()前,则该自定义拦截器为前处理拦截器,置于之后则该拦截器为后处理拦截器。
拦截器的最终返回结果是视图逻辑名(也就是各种action的执行result的name属性),如果自定义拦截器中不使用invacation.invoke()获得放行的结果,直接返回字符串(这通常意味着请求并没有通过拦截器的验证逻辑),那么Struts2会根据对应的视图逻辑名返回视图资源。
就关于视图逻辑名,其实在SpringMVC中,我们在Controller类中,返回的字符串 ,通常也是视图逻辑名。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值