项目做完也有好几天了,一直想总结一下,主要是记录一下,自己在项目中做的事情,以及遇到了什么问题,遇到问题的解决方法。
项目采用的开发技术是spring+struts2+mybatis+shiro,前段技术主要采用了jquery+easyui以及jquery的一些插件。前台获取数据主要采用ajax向后台发送请求,获取json格式的数据,表单采用ajax表单提交。
一、统一日志处理
一开始同事是想着在action层写一个公用的添加日志的方法,然后在action类的每个方法中调用这个方法,即下面这种方式
protected int addLog(...) {
}
class Action1 {
public String xx() {
addLog(...);
}
}
虽然这种方式可以实现功能,但我觉得不太好,一是代码不够优雅,二是这种方式只能在当前层调用,调用范围受限制,三是因为异常日志也要记录到数据库,这样就需要在action的方法中采用try{}catch方式,而每个方法都添加try{}catch,工作量也不小,而且我们打算将action层的异常进行统一处理,无需每个方法都使用try{}catch捕获异常。经过讨论后,我打算采用spring aop统一处理日志,同时采用枚举的方式,判断调用哪些方法时,需要添加日志以及添加日志的数据信息。
枚举类:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessLogMeta {
public EResource resource();
public EOper operate();
public String desc();
}
service层:
@AccessLogMeta(resource=EResource.ACCOUNT,operate=EOper.CREATE,desc="新增商户")
public Map<String, Object> insert(BusinessVo entity, Map<String, ? extends Object> ext) {
。。。
}
aop的切面:
@Aspect
@Component
public class AccessLogAspect {
/**
* 返回后通知:@AfterReturning和@After的区别是@AfterReturning有返回值
*/
@AfterReturning(pointcut="execution(* ....*Service.*(..)) && @annotation(accessLogMeta)")
public void adviceCall(JoinPoint point, AccessLogMeta accessLogMeta) {
this.addAccessLog(accessLogMeta, false);
}
/**
* 抛出异常后通知
*/
@AfterThrowing(pointcut="execution(* ....*Service.*(..)) && @annotation(accessLogMeta)")
public void throwAdviceCall(JoinPoint point, AccessLogMeta accessLogMeta) {
this.addAccessLog(accessLogMeta, true);
}
/**
* 添加日志
* @param accessLogMeta 日志元数据的注解
* @param exceptionFlag 是否是出现异常时的日志标志
*/
private void addAccessLog(AccessLogMeta accessLogMeta, boolean exceptionFlag) {
。。。
}
}
注:@annotation(accessLogMeta)表示只有用accessLogMeta注解标识的方法才会被通知,pointcut就是切入点
这样就完成了aop 统一日志处理。