开发中肯定会遇到一个类,需要添加多个拦截器的情况,在这种情况下,我们就需要通过拦截器链来解决这个问题,在Seasar2中,实现拦截器链的思路是在配app.dicon文件中配置
org.seasar.framework.aop.interceptors.InterceptorChain
,这个类就是链拦截器,核心还是继承了AbstractInterceptor的类,然后配置拦截器到组建中,案例源码地址:https://git.oschina.net/yellowcong/seasar
拦截器配置
我自定义了两个拦截器,然后将两个拦截器配置到了一个组中,构成了拦截器链,然后在将这个连接器链植入到组建中
<!-- 配置了两个拦截器 -->
<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