在Seasar2中Aop的实现方法有很多种,我先介绍一下,通过继承AbstractInterceptor(这是一个抽象类,继承了MethodInterceptor, Serializable连个接口)来实现拦截器或直接实现MethodInterceptor的接口,然后在app.icon配置文件中配置切面,最后通过seasar2获取织入的组件对象,这样就完成了seasar2的切面配置操作,通常可以通过拦截器做权限、日志、事物等的管理。
AOP的应用和场景
1、日志记录,跟踪,优化和监控
2、事务的处理
3、持久化
4、性能的优化
5、资源池,如数据库连接池的管理
6、系统统一的认证、权限管理等
7、应用系统的异常捕捉及处理
8、针对具体行业应用的横切行为
MeasurementInterceptor
这个类是一个拦截器,是用于计算时间的,需要继承AbstractInterceptor(这是一个抽象类,继承了MethodInterceptor, Serializable连个接口),也可以直接通过实现MethodInterceptor接口,然后复写invoke的方法,写成我们自己的业务。
package com.yellowcong.interceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.aop.interceptors.AbstractInterceptor;
/**
*
*作者:yellowcong</br>
*日期:2017/08/30
*時間:16:47:45
*描述:用于计算调用方法所耗费的时间
*/
public class MeasurementInterceptor extends AbstractInterceptor{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//建立一个100长度的StringBuffer
StringBuffer buf = new StringBuffer(100);
long start =0;
long end = 0;
//获取当前调用的类类名称
buf.append(getTargetClass(invocation).getName());
buf.append("#");
//调用的方法名称
buf.append(invocation.getMethod().getName());
buf.append("(");
//执行的参数
Object[] args = invocation.getArguments();
if (args != null && args.length > 0) {
for (int i = 0; i < args.length; ++i) {
buf.append(args[i]);
buf.append(", ");
}
buf.setLength(buf.length() - 2);
}
buf.append(")");
try {
start = System.currentTimeMillis();
//执行传入的方法
Object ret = invocation.proceed();
//系统毫秒数
end = System.currentTimeMillis();
return ret;
}catch(Exception e){
e.printStackTrace();
}finally {
System.out.println(buf.toString()+"花费时间"+(end-start));
}
return null;
}
}
UserTest
这是一个需要织入拦截器的类,我们通过拦截器来计算调用say方法,所需要的时间。定义组建的时候,不能将一个类,定义成两个相同的组建,可以取不同的名称来解决一个类,配置多个组建的问题,在配置拦截器的时候,还可以采用拦截器链
package com.yellowcong.aop.test;
/**
*
*作者:yellowcong
*日期:2017/09/04
*時間:8:53:41
*描述:
*/
public class UserTest {
public void say() {
System.out.println("调用了切面程序");
}
}
app.dicon
需要在app.dicon 配置拦截器和织入拦截器
<!--拦截器-->
<component name="measurement"
class="com.yellowcong.interceptor.MeasurementInterceptor" />
<!--需要在say方法中织入拦截器-->
<component class="com.yellowcong.aop.test.UserTest">
<!-- 织入的点和拦截器 -->
<aspect pointcut="say"> measurement </aspect>
</component>
测试方法及结果
继承S2DaoTestCase 类,然后在setUp方法中,配置seasar2容器配置文件,然后获取组建UserTest,我们需要通过Seasar2容器来获取组建,这样才有拦截器,直接new的方法,不可能有拦截器
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 Demo11 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();
}
}
测试结果
测试结果中,调用了拦截器
[2017/09/04 08:55:17] DEBUG [S2ContainerFactory]: S2Containerを作成します。path=app.dicon
[2017/09/04 08:55:17] DEBUG [S2ContainerFactory]: S2Containerを作成します。path=dao.dicon
[2017/09/04 08:55:17] DEBUG [S2ContainerFactory]: S2Containerを作成します。path=j2ee.dicon
[2017/09/04 08:55:18] DEBUG [S2ContainerFactory]: S2Containerを作成しました。path=j2ee.dicon
[2017/09/04 08:55:18] DEBUG [S2ContainerFactory]: S2Containerを作成しました。path=dao.dicon
[2017/09/04 08:55:18] DEBUG [S2ContainerFactory]: S2Containerを作成しました。path=app.dicon
[2017/09/04 08:55:18] WARN [BindingTypeShouldDef]: com.yellowcong.action.UserActionのプロパティ(container)が見つからないので設定をスキップします
调用了切面程序
com.yellowcong.aop.test.UserTest#say()花费时间1