Spring切面編程例子

/**============================================================
 * 版權: 
 * 包: com.after90s.frame.aspectj
 * 修改記錄:
 * 日期                作者           內容
 * =============================================================
 * 2019年7月31日       LJW        
 * ============================================================*/

package com.after90s.frame.aspectj;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

import com.after90s.common.annotation.Log;
import com.after90s.common.utils.ShiroUtils;
import com.after90s.project.web.user.entity.UserEntity;

/**
 * <p>
 * TODO Log註解切面操作相關 可以把重要的操作保存到數據庫
 * </p>
 *
 *
 * @author AINY
 * @version 2019年7月31日
 */
@Aspect // 作用是把當前類標識爲一個切面供容器讀
@Component
@EnableAsync // 啓用異步任務
public class LogAspectJ {
//	private static final Logger log = LoggerFactory.getLogger(LogAspectJ.class);

	/*
	 * 配置織入點 也可以切入包、方法,本次切入的是自定義的註解
	 * 
	 * @Pointcut("execution(* com.after90s.Student.getName(..))")
	 * 
	 * @Pointcut("execution(* com.after90s.*.*(..))")
	 */
	@Pointcut("@annotation(com.after90s.common.annotation.Log)")
	/**
	 * signature
	 *  void
	 */
	public void logCutPoint() {
		
	}

	/**
	 * 執行前 void
	 */
	@Before("logCutPoint()")
	public void beforeAdvice() {
		System.out.println("======================方法執行前===================");
	}

	/**
	 * 執行後 void
	 */
	@After("logCutPoint()")
	public void afterAdvice() {
		System.out.println("======================方法執行後===================");
	}

	/**
	 * 方法返回對象前 void
	 */
	@AfterReturning(pointcut = "logCutPoint()", returning = "joinPoint")
	public void afterReturningAdvice(JoinPoint joinPoint) {
		handleLog(joinPoint, null);
	}

	/**
	 * 出現異常時
	 * 
	 * @param joinPoint
	 * @param e         void
	 */
	@AfterThrowing(value = "logCutPoint()", throwing = "e")
	public void doAfter(JoinPoint joinPoint, Exception e) {
		handleLog(joinPoint, e);
	}

	/**
	 * 異步操作記錄日誌
	 * 
	 * @param joinPoint
	 * @param e         void
	 */
	@Async
	private void handleLog(final JoinPoint joinPoint, final Exception e) {
		// 獲得註解
		Log controllerLog = getMyAnnotationLog(joinPoint);
		if (controllerLog == null) {
			return;
		}
		// 設置方法民名稱和類明名稱
		String className = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		if (currentUser != null) {
			System.out
					.println("=================="  "操作:" + className + "." + methodName);
		}
		if (e != null) {
			System.out.println("===================" + e.getMessage() + "操作:" + className + "." + methodName);
		}
	}

	/**
	 * 獲取註解 沒有則返回null
	 * 
	 * @param joinPoint
	 * @return Log
	 */
	private Log getMyAnnotationLog(JoinPoint joinPoint) {
		// 獲取切點簽名
		Signature signature = joinPoint.getSignature();
		// 方法簽名
		MethodSignature methodSignature = (MethodSignature) signature;
		// 方法
		Method method = methodSignature.getMethod();
		if (method != null && method.getAnnotation(Log.class) != null) {
			return method.getAnnotation(Log.class);
		}
		return null;
	}
}

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