1. 程式人生 > 實用技巧 >AOP中ProceedingJoinPoint獲取目標方法,引數,註解

AOP中ProceedingJoinPoint獲取目標方法,引數,註解

private void saveLog(ProceedingJoinPoint jp,long time)throws Throwable {
            package com.cy.pj.common.aspect;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.cy.pj.common.annotation.RequiredLog;
import com.cy.pj.common.util.IPUtils;
import com.cy.pj.sys.entity.SysLog;
import com.cy.pj.sys.service.SysLogService;

import lombok.
extern.slf4j.Slf4j; /** * @Aspect 描述的類為切面類,此類中實現: * 1)切入點(Pointcut)的定義 * 2)通知(advice)的定義(擴充套件功能) */ @Slf4j @Aspect @Component public class SysLogAspect { /** * @Pointcut 註解用於描述或定義一個切入點 * 切入點的定義需要遵循spring中指定的表示式規範 例如:("bean(sysMenuServiceImpl)")為切入點表示式 的一種定義方式。
*/ //bean(bean名稱或一個表示式) //@Pointcut("bean(sysMenuServiceImpl)") @Pointcut("@annotation(com.cy.pj.common.annotation.RequiredLog)") public void logPointCut() {} /** * @Around 註解描述的方法為一個環繞通知方法, * 在此方法中可以新增擴充套件業務邏輯,可以呼叫下一個 切面物件或目標方法 * @param jp 連線點(此連線點只應用@Around描述的方法) * @return * @throws Throwable
*/ @Around("logPointCut()") public Object aroundAdvice(ProceedingJoinPoint jp) throws Throwable{ long start=System.currentTimeMillis(); log.info("start:"+start); Object result=jp.proceed();//呼叫下一個切面或目標方法 long end=System.currentTimeMillis(); log.info("end:"+end); //記錄日誌(使用者行為資訊) saveLog(jp,(end-start)); return result; } @Autowired private SysLogService sysLogService; //日誌記錄 private void saveLog(ProceedingJoinPoint jp,long time)throws Throwable { //1.獲取使用者行為日誌(ip,username,operation,method,params,time,createdTime) //獲取類的位元組碼物件,通過位元組碼物件獲取方法資訊 Class<?> targetCls=jp.getTarget().getClass(); //獲取方法簽名(通過此簽名獲取目標方法資訊) MethodSignature ms=(MethodSignature)jp.getSignature(); //獲取目標方法上的註解指定的操作名稱 Method targetMethod= targetCls.getDeclaredMethod( ms.getName(), ms.getParameterTypes()); RequiredLog requiredLog= targetMethod.getAnnotation(RequiredLog.class); String operation=requiredLog.value(); System.out.println("targetMethod="+targetMethod); //獲取目標方法名(目標型別+方法名) String targetClsName=targetCls.getName(); String targetObjectMethodName=targetClsName+"."+ms.getName(); //獲取請求引數 String targetMethodParams=Arrays.toString(jp.getArgs()); //2.封裝使用者行為日誌(SysLog) SysLog entity=new SysLog(); entity.setIp(IPUtils.getIpAddr()); entity.setUsername("admin"); entity.setOperation(operation); entity.setMethod(targetObjectMethodName); entity.setParams(targetMethodParams); entity.setTime(time); entity.setCreatedTime(new Date()); //3.呼叫業務層物件方法(saveObject)將日誌寫入到資料庫 sysLogService.saveObject(entity); } } }

https://www.yuque.com/binarylei/java/annotation