开发中肯定会遇到一个类,需要添加多个拦截器的情况,在这种情况下,我们就需要通过拦截器链来解决这个问题,在Seasar2中,实现拦截器链的思路是在配app.dicon文件中配置org.seasar.framework.aop.interceptors.InterceptorChain,这个类就是链拦截器,核心还是继承了AbstractInterceptor的类,然后配置拦截器到组建中

拦截器配置

我自定义了两个拦截器,然后将两个拦截器配置到了一个组中,构成了拦截器链,然后在将这个连接器链植入到组建中

<!-- 配置了两个拦截器 --> 
  <component name="interceptor1"
 class="com.yellowcong.interceptor.Interceptor1" />
  <component name="interceptor2"
 class="com.yellowcong.interceptor.Interceptor2" />


    <!--一个拦截器链 -->
  <component name="interceptorChain" class="org.seasar.framework.aop.interceptors.InterceptorChain">
    <!-- 调用dao.dicon下的interceport拦截器, -->
    <initMethod name="add"><arg>interceptor1</arg></initMethod>
    <initMethod name="add"><arg>interceptor2</arg></initMethod>
  </component>

       <!-- 设定组建拦截器 -->
    <component class="com.yellowcong.aop.test.UserTest">
        <!-- 织入的点和拦截器 -->
        <aspect pointcut=".*"> interceptorChain </aspect>
    </component>

拦截器一


这个拦截器是通过实现MethodInterceptor 接口,完成的自定义拦截器,需要注意的,return后面如果还需要执行代码,需要放到finally 里面,放到代理对象,执行proceed后面,是不会执行的,这点一定要记住了

package com.yellowcong.interceptor;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
 *
 * 作者:yellowcong</br>
 * 日期:2017/08/30 時間:16:47:45 描述:用于计算调用方法所耗费的时间
 */
public class Interceptor1 implements MethodInterceptor {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        try {
            System.out.println("第一个拦截器 BEGIN");
            // 执行传入的方法
            Object ret = invocation.proceed();

            return ret;
        }finally {
            System.out.println("第一个拦截器 END");
        }

    }

}

拦截器二

package com.yellowcong.interceptor;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.aop.interceptors.AbstractInterceptor;

/**
 *
 * 作者:yellowcong</br>
 * 日期:2017/08/30 時間:16:47:45 描述:用于计算调用方法所耗费的时间
 */
public class Interceptor2 implements MethodInterceptor {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {

        try {
            System.out.println("第二个拦截器 BEGIN");
            // 执行传入的方法
            Object ret = invocation.proceed();


            return ret;

        }finally {
            // 系统毫秒数
            System.out.println("第二个拦截器 END");
        }
    }
}

业务类

package com.yellowcong.aop.test;
/**
*
*作者:yellowcong
*日期:2017/09/04
*時間:8:53:41
*描述:
*/
public class UserTest {

    public void say() {
        System.out.println("调用了切面程序");
        throw new RuntimeException("test");
    }

    public void say2() {
        System.out.println("调用了切面程序");
        throw new RuntimeException("test");
    }
}

测试类

package com.yellowcong.test;

import java.util.Date;

import org.junit.Test;
import org.seasar.dao.unit.S2DaoTestCase;

import com.yellowcong.aop.test.UserTest;

/**
 *
 * 作者:yellowcong 日期:2017/09/04 時間:8:41:42 描述:
 */
public class Demo12 extends S2DaoTestCase {

    protected void setUp() throws Exception {
        super.setUp();
        include("app.dicon");
    }


    @Test
    public void testAop() {
        UserTest user = (UserTest) this.getComponent(UserTest.class);
        user.say();
        user.say2();
    }
}

测试结果
测试发现,调用了两个方法,却只执行了一个方法,而且拦截器的的执行顺序是和拦截器定义的先后顺序执行的

[2017/09/04 09:50:25] DEBUG [S2ContainerFactory]: S2Containerを作成します。path=app.dicon
[2017/09/04 09:50:25] DEBUG [S2ContainerFactory]: S2Containerを作成します。path=dao.dicon
[2017/09/04 09:50:25] DEBUG [S2ContainerFactory]: S2Containerを作成します。path=j2ee.dicon
[2017/09/04 09:50:25] DEBUG [S2ContainerFactory]: S2Containerを作成しました。path=j2ee.dicon
[2017/09/04 09:50:25] DEBUG [S2ContainerFactory]: S2Containerを作成しました。path=dao.dicon
[2017/09/04 09:50:25] DEBUG [S2ContainerFactory]: S2Containerを作成しました。path=app.dicon
[2017/09/04 09:50:25] WARN  [AopProxy]: com.yellowcong.aop.test.UserTestのメソッド(wait)にはアスペクトを適用できない修飾子が指定されています
[2017/09/04 09:50:25] WARN  [AopProxy]: com.yellowcong.aop.test.UserTestのメソッド(wait)にはアスペクトを適用できない修飾子が指定されています
[2017/09/04 09:50:25] WARN  [AopProxy]: com.yellowcong.aop.test.UserTestのメソッド(wait)にはアスペクトを適用できない修飾子が指定されています
[2017/09/04 09:50:25] WARN  [AopProxy]: com.yellowcong.aop.test.UserTestのメソッド(getClass)にはアスペクトを適用できない修飾子が指定されています
[2017/09/04 09:50:25] WARN  [AopProxy]: com.yellowcong.aop.test.UserTestのメソッド(notify)にはアスペクトを適用できない修飾子が指定されています
[2017/09/04 09:50:25] WARN  [AopProxy]: com.yellowcong.aop.test.UserTestのメソッド(notifyAll)にはアスペクトを適用できない修飾子が指定されています
[2017/09/04 09:50:25] WARN  [BindingTypeShouldDef]: com.yellowcong.action.UserActionのプロパティ(container)が見つからないので設定をスキップします
第一个拦截器 BEGIN
第二个拦截器 BEGIN
调用了切面程序2
第二个拦截器 END
第一个拦截器 END