spring中使用AOP进行日志记录[含代码]

haidaoxianzi 2017-09-13

spring的IOC和AOP是说的最烂的东西,尤其是后者,给编码带来很多很多的方便,网上不上代码都说了AOP主要用来做日志记录,异常处理,记录程序执行时间,缓存这样的事情,但是不少只是简单的做一个说明,没有代码,这里我把项目中实际使用的抽出来,本文主要是关于最简单的日志的记录。

前提:需要对spring aop概念有所了解,以及有spring开发经验,了解自定义注解。如果不明白,看下面的文章:

Spring思维导图,让Spring不再难懂(aop篇)

深入理解Java:注解(Annotation)自定义注解入门

-----------------------------------------------------------------------------------------------------------

下面进入正题:最终使用的效果如下:

@Service 
public class TallyTypeService extends CrudService<TallyTypeDao, TallyType> {   
	.....

	@LoggerPoint(pointKey=PointerKey.MONEY_TALLYTYPE)
	public Page<TallyType> findPage(Page<TallyType> page, TallyType entity) {
		return super.findPage(page,entity);
	} 

	......
}
使用了自定义注解, LoggerPoint标明要记录当前方法的执行参数,执行时间,执行类别等信息。pointKey是一个业务的分类。
/**
 * 对于日志注入点的功能说明枚举.
 * @author Administrator
 *
 */
public enum PointerKey {
	ALL("全部"), SINGLE("单接口"), UNKNOW("未知接口"), Test("测试"), MONEY_TALLYTYPE(
			"金额类型");

	private String name;

	private PointerKey(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
 

对于LoggerPoint注解,很简单:

@Retention(RetentionPolicy.RUNTIME) 
@Target({ ElementType.METHOD })
public @interface LoggerPoint {
	public PointerKey pointKey();
}
 

关键的是,使用解析上面注解的切面类:

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.renjie120.common.enums.PointerKey;
import com.renjie120.common.utils.JsonUtils;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LoggerAspect {
	public static Logger logger = LoggerFactory.getLogger(LoggerAspect.class);
	
	private Method getMethod(ProceedingJoinPoint pjp){
		Signature signature = pjp.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method method = methodSignature.getMethod();
		return method;
	}
	
	@Around("@annotation(com.renjie120.common.aspect.LoggerPoint)")
	public Object trafficInterface(ProceedingJoinPoint pjp) throws Throwable {
		Method method = this.getMethod(pjp);
		LoggerPoint loggerPoint = method.getAnnotation(LoggerPoint.class);
		PointerKey pointerKey = loggerPoint.pointKey(); 
		
		Object[] args = pjp.getArgs();
		Map<String,Object> paramMap = new HashMap<String,Object>();
		
		for(Object arg:args){
			paramMap.put(arg.getClass().getSimpleName(), arg);
		}
		
		String requestJson = JsonUtils.toJsonStr(paramMap);
		String gid= UUID.randomUUID().toString();
		
		System.out.println("请求参数:"+requestJson);
		
		Object returnObj = null;
		String errorMsg = null;
		try {
			System.out.println("当前执行:"+method.getName()+"---"+pointerKey.name()+",gid="+gid);returnObj = pjp.proceed();
			return returnObj;
		} catch (Exception e) {
			errorMsg = ExceptionUtils.getStackTrace(e);
			logger.error(e.getMessage(),e);
			throw e;
		} finally {
			if (returnObj == null) {
				returnObj = errorMsg;
			}
			System.out.println("响应:"+JsonUtils.toJsonStr(returnObj));
		}    
	}
 
}
 1、上面的注解@Component,@Aspect为spring 注解,需要放在扫描路径中:

相关推荐