spring中使用AOP進行日誌記錄[含代碼]

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 註解,需要放在掃描路徑中:
<context:component-scan base-package="com.renjie120"  >

	</context:component-scan>
 2、上圖的@Around註解,標明使用的是環繞切面。
 3、打印日誌這裏是直接system.out出來,實際項目中可以保存到數據庫日誌表中,對於大量數據爲不影響操作,可以先保存到隊列中,再從隊列中取出異步保存到數據庫中。
 4、在實際使用中,也可以使用配置xml方式聲明上面的切面處理類,這種情況就不需要使用上面的@Component,@Aspect,@Around註解
在spring-context.xml中:
<bean id="loggerAspect" class="com.renjie120.common.annotation.log.LoggerAspect" />
	
<aop:config>
			
		<aop:pointcut id="loginPointer"
			expression="@annotation(com.renjie120.common.annotation.log.LoggerPoint)" /> 
			
		<aop:aspect id="aspect" ref="loggerAspect">

			<aop:around method="trafficInterface" pointcut-ref="loginPointer" />

		</aop:aspect> 
		 
	</aop:config>
 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章