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)
@Documented
public @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;

@Aspect
public 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类。

你可能感兴趣的:(spring aop)