spring Aop 之用户操作日志以及异常处理日志记录
使用Aop做操作日志,异常处理,并记录日志。
方法1:try{}catch(){记录日志}
方法2:通过filter,或者strtus2拦截器(目前项目是struts2)
方法3:hirbernate的拦截器记录日志
方法4:通过jvm agent 代理
方法5:自定义类加载器应该也可以
虽然说各有个的好处吧,但是我个人还是喜欢Aop,当然Aop有多种实现。目前项目上用的是Spring Aop的 Aspect 。
我觉得使用Aop会更加的解耦合,更加的从其他的业务代码中分离出来。和上一篇做方法缓存差不多,上代码。
?
首先定义个注解,用于记录该方法的描述
import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface MethodLog {String remark() default "";}?
???Action类
????
public class Sev {@MethodLog(remark="增加用户信息")public String addUser(int type,int parentid){return "";}}?
? Aop 类
? ?
?
package com.zhang.shine.cache;import java.lang.reflect.Method;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;@Aspectpublic class MethodLogAspectJ {@Pointcut("@annotation(com.zhang.shine.cache.MethodLog)")public void methodCachePointcut() {}@Around("methodCachePointcut()")public Object methodCacheHold(ProceedingJoinPoint joinPoint)throws Throwable {System.out.println("aop start ");String methodRemark = getMthodRemark(joinPoint);Object result = null;try {// 记录操作日志...谁..在什么时间..做了什么事情..result = joinPoint.proceed();} catch (Exception e) {// 异常处理记录日志..log.error(e);throw e;}System.out.print(methodRemark);System.out.println("aop end ");return result;}// 获取方法的中文备注____用于记录用户的操作日志描述public static String getMthodRemark(ProceedingJoinPoint joinPoint)throws Exception {String targetName = joinPoint.getTarget().getClass().getName();String methodName = joinPoint.getSignature().getName();Object[] arguments = joinPoint.getArgs();Class targetClass = Class.forName(targetName);Method[] method = targetClass.getMethods();String methode = "";for (Method m : method) {if (m.getName().equals(methodName)) {Class[] tmpCs = m.getParameterTypes();if (tmpCs.length == arguments.length) {MethodLog methodCache = m.getAnnotation(MethodLog.class);methode = methodCache.remark();break;}}}return methode;}}?? <aop:config>节点中proxy-target-class="true"不为true时。
当登录的时候会报这个异常java.lang.NoSuchMethodException: $Proxy54.login(),
是因为代理Action类的时候,如果Proxy-targer-class=false,默认是用jdk动态代理。
所以代理不了Action类。