1. 程式人生 > >java web日誌記錄之spring aop實現方式

java web日誌記錄之spring aop實現方式

實現思路:spring aop切入到bean,在需要寫日誌的方法加入註解AuditLog,如果沒有註解的方法則不記錄日誌。

註解類

@Target({ElementType.PARAMETER, ElementType.METHOD})    
@Retention(RetentionPolicy.RUNTIME)    
@Documented 
public @interface AuditLog {
	 String description()  default "";//操作內容
	 StoreLogType logType() default StoreLogType.All;//操作型別
}

spring aop切入類
@Aspect
@Component
public class StoreLogCut {
	private static final Logger logger = LoggerFactory.getLogger(StoreLogCut.class);
	
	private static final String storeLogJsonParams = "storeLogJsonParams";//切入Controller請求引數為json型別需要將請求物件賦予該名稱的屬性,以便獲取請求引數

	private StoreLogService storeLogService;

	/**
	 * Controller層切入點
	 */
	@Pointcut("execution(public * com.cd.store.controller.*.*(..))")
	public void controllerAspect() {
	}

	/**
	 * 後置返回通知
	 * 
	 * @param joinpoint
	 * @param returnValue
	 * @throws Throwable
	 */
	@AfterReturning(value = "controllerAspect()", returning = "returnValue")
	public void after(JoinPoint joinpoint, Object returnValue) throws Throwable {
		writeLog(joinpoint, returnValue);
	}

	/**
	 * 異常返回通知
	 * 
	 * @param joinpoint
	 * @param errorMsg
	 */
	@AfterThrowing(value = "controllerAspect()", throwing = "errorMsg")
	public void afterThrowException(JoinPoint joinpoint, Exception errorMsg) {
		writeLog(joinpoint, errorMsg);
	}

	/**
	 * 記錄日誌
	 * 
	 * @param joinpoint
	 * @param obj
	 */
	private void writeLog(JoinPoint joinpoint, Object obj) {
		try {
			HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
					.getRequest();
			StoreLogDescDto storeLogDescDto = getControllerMethodDescription(joinpoint);
			String action = storeLogDescDto.getAction();
			// 如果加了日誌註解類則寫入日誌到資料庫
			if (StringUtils.isNotBlank(action)) {
				int result = StoreLogResultType.success.getType();
				String returnMsg = "";
				if (obj instanceof Exception) {// 異常通知
					result = StoreLogResultType.Error.getType();
					returnMsg = ((Exception) obj).getMessage();
				} else {// 正常返回通知
					returnMsg = String.valueOf(obj);
					// 解析返回的資料(如返回false則為失敗)
					result = getProcessResult(returnMsg);
				}
				String userName = getUserName(request);// 獲取操作人
				String ip = Utils.getRequestIp(request);// 獲取客戶端ip地址
				String param = Utils.getParam(request,joinpoint,storeLogJsonParams);// 獲取請求引數
				String requestUrl = String.valueOf(request.getRequestURL());
				storeLogService.insertLog(userName, ip, param, action, storeLogDescDto.getType(), result, returnMsg,requestUrl);
			}
		} catch (Exception e) {
			String errorMsg = new StringBuilder().append("write log to database error,").append(e.getMessage())
					.toString();
			logger.error(errorMsg);
		}
	}

	private int getProcessResult(String returnMsg) {
		if (StringUtils.isNotBlank(returnMsg) && "false".equalsIgnoreCase(returnMsg)) {
			return StoreLogResultType.Error.getType();
		}
		return StoreLogResultType.success.getType();
	}

	/**
	 * 獲取使用者名稱
	 * 
	 * @param request
	 * @return
	 */
	private String getUserName(HttpServletRequest request) {
		HttpSession session = request.getSession();
		Object userNameObj = session.getAttribute(Constants.SS_ACCOUNT);
		String userName = "";
		if (userNameObj != null) {
			userName = (String) userNameObj;
		}
		return userName;
	}

	/**
	 * 獲取註解中對方法的描述資訊 用於Controller層註解
	 * 
	 * @param joinPoint
	 *            切點
	 * @return 方法描述
	 * @throws Exception
	 */
	private StoreLogDescDto getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		StoreLogDescDto storeLogDescDto = new StoreLogDescDto();
		String description = "";
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					AuditLog storeLogAnnotation = method.getAnnotation(AuditLog.class);
					if (storeLogAnnotation != null) {
						description = storeLogAnnotation.description();
						int type = storeLogAnnotation.logType().getType();
						storeLogDescDto.setAction(description);
						storeLogDescDto.setType(type);
						break;
					}
				}
			}
		}
		return storeLogDescDto;
	}

	public StoreLogService getStoreLogService() {
		return storeLogService;
	}

	@Autowired
	@Required
	public void setStoreLogService(StoreLogService storeLogService) {
		this.storeLogService = storeLogService;
	}


相關推薦

java web日誌記錄spring aop實現方式

實現思路:spring aop切入到bean,在需要寫日誌的方法加入註解AuditLog,如果沒有註解的方法則不記錄日誌。 註解類 @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(Ret

Java多執行緒四種實現方式

介紹 繼承Thread類,並重寫其run方法 實現Runnable介面 實現Callable介面通過FutureTask包裝器來建立Thread執行緒 執行緒池,使用ExecutorService、Callable、Future實現有返回結果的多執行緒。 其

Spring AOP實現方式

Spring 實現AOP有兩種方式, JDK動態代理和CGLIB代理,Spring會根據攔截物件來選擇何種實現。 如果攔截物件至少實現了一個介面,則會使用JDK動態代理,所有改目標類實現的介面都將被代理。 如果攔截物件沒有實現任何介面,則會建立一個CGLIB代理。  如果

springboot—spring aop 實現系統操作日誌記錄存儲到數據庫

work prop 請求 pack spa 成功 方法 代碼 shu 原文:https://www.jianshu.com/p/d0bbdf1974bd 采用方案: 使用spring 的 aop 技術切到自定義註解上,針對不同註解標誌進行參數解析,記錄日誌

JAVA WEB快速入門通過一個簡單的Spring專案瞭解Spring的核心(AOP、IOC)

接上篇《JAVA WEB快速入門之從編寫一個JSP WEB網站了解JSP WEB網站的基本結構、除錯、部署》,通過一個簡單的JSP WEB網站了解了JAVA WEB相關的知識,比如:Servlet、Fitler、Listner等,這為後面搭建基於SSM的框架奠定了基礎知識,當然光了解JSP相關的知識還不行,我

自定義註解+Spring AOP實現記錄使用者操作日誌

一、背景     專案中需要對使用者的各種操作做詳細的操作日誌記錄,需要記錄使用者操作的操作模組、具體操作以及操作的資料記錄ID等。     若寫一個方法去儲存操作,則需要每次手動去呼叫。由於是非業務性的操作,並且大量的重複操作,Spring AOP就能很好的解決這個問題。

Java框架Spring AOP 面向切面程式設計 有哪幾種實現方式?如何選擇適合的AOP實現方式

文章目錄 1. 實現方式 2. JDK動態代理如何實現? 2.1 主要的實現過程 3. 如何選擇? 1. 實現方式 JDK 動態代理實現和 cglib 實現 2. JDK

Spring Aop實現簡單日誌記錄

日誌類 package com.jusfoun.estate.log.domain; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import java

Spring AOP實現日誌記錄(Aspect)

一、Aop術語 切面(Aspect):在Spring AOP中,切面可以使用通用類或者在普通類中以@Aspect 註解(@AspectJ風格)來實現 連線點(Joinpoint):在Spring AOP中一個連線點代表一個方法的執行 通知(Advice):在切面的某個特定的連線點(Joinp

使用自定義註解+Spring AOP 實現日誌記錄

使用自定義註解+Spring切面 實現日誌記錄 在平常的專案程式設計中,我們會經常使用到日誌,用來記錄各種事件.但是,有些日誌記錄套路實在是太像了,我們不得不要寫很多遍. 比如在Spring中,我們要使用日誌記錄每個controller的訪問和結束時間,該怎

spring aop 實現使用者操作日誌記錄功能

首先寫好一個工具類 LogAspect.java package com.yangjf.commons; import java.lang.reflect.Method; import java.util.Date; import org.aspectj.lang.Join

Spring Aop實現使用者操作日誌記錄

package com.jixi.controller; import com.jixi.pojo.Log; import com.jixi.pojo.User; import com.jixi.service.ILogService; import com.jixi.service.IUserServic

java中代理,靜態代理,動態代理以及spring aop代理方式實現原理統一彙總 SpringAOP的兩種代理方式Java動態代理和CGLIB代理)

若代理類在程式執行前就已經存在,那麼這種代理方式被成為 靜態代理 ,這種情況下的代理類通常都是我們在Java程式碼中定義的。 通常情況下, 靜態代理中的代理類和委託類會實現同一介面或是派生自相同的父類。 一、概述1. 什麼是代理我們大家都知道微商代理,簡單地說就是代替廠家賣商品,廠家“委託”代理為

Spring裡的aop實現方式和原始碼分析 java中代理,靜態代理,動態代理以及spring aop代理方式實現原理統一彙總

使用"橫切"技術,AOP把軟體系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處基本相似,比如許可權認證、日誌、事務。AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。

Mybatis(四):MyBatis核心元件介紹原理解析和原始碼解讀 java中代理,靜態代理,動態代理以及spring aop代理方式實現原理統一彙總

Mybatis核心成員 Configuration        MyBatis所有的配置資訊都儲存在Configuration物件之中,配置檔案中的大部分配置都會儲存到該類中 SqlSession         &

Java框架(六)Spring(AOP)

1.介紹 AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護(增強方法)的一種技術。 AOP是OOP(面向物件程式設計)的延續,是軟體開發中的一個熱點,也是Spri

Java框架Spring AOP 面向切面 中的連線點與切點是什麼?

連線點 定義:連線點是一個應用執行過程中能夠插入一個切面的點。 連線點可以是呼叫方法時、丟擲異常時、甚至修改欄位時、 切面程式碼可以利用這些點插入到應用的正規流程中。使得程式執行過程中能夠應用通知的所有點。 切點 定義:如果通知定義了“什麼”和“何時”,那麼切點就定

Java框架Spring AOP (Aspect Oriented Programming) 面向切面程式設計是什麼?

Spring AOP是什麼? Spring AOP是面向切面程式設計,將功能程式碼從業務邏輯程式碼中分離出來。 它允許程式通過分離的應用業務邏輯與系統級別服務。 程式設計師只需專注自己的業務邏輯,而不需要管系統級服務。 容器中的物件能享有容器中的公共服務(日誌、安全)。

Java定時器(二)Spring定時任務、Quartz實現

使用基於註解配置的spring定時器 基於註解會相對簡單的多,直接編寫任務類Mytask @EnableScheduling @Component public class Mytask { @Scheduled(cron = "*/5 * * * * ?") p

spring aop 實現controller 日誌

@Aspect @Component @Slf4j public class ControllerAspact { @Pointcut("execution(public * com.example.controller..*.*(..))") public void requestLog(