import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.StopWatch; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; /** * @author kelin.ll * @date on 2019/6/5 */ @Aspect @Component @Slf4j public class AuthAspect {/** * 這個切點的表達式須要根據本身的項目來寫 * 說明: * execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?) * 修飾符匹配(modifier-pattern?) * 返回值匹配(ret-type-pattern)能夠爲*表示任何返回值,全路徑的類名等 * 類路徑匹配(declaring-type-pattern?) * 方法名匹配(name-pattern)能夠指定方法名 或者 *表明全部, set* 表明以set開頭的全部方法 * 參數匹配((param-pattern))能夠指定具體的參數類型,多個參數間用「,」隔開,各個參數也能夠用「*」來表示匹配任意類型的參數,如(String)表示匹配一個String參數的方法;(*,String) 表示匹配有兩個參數的方法,第一個參數能夠是任意類型,而第二個參數是String類型;能夠用(..)表示零個或多個任意參數 * 異常類型匹配(throws-pattern?) * 其中後面跟着「?」的是可選項 * * 如: * 1)execution(* *(..)) 表示匹配全部方法 * 2)execution(public * com. savage.service.UserService.*(..)) 表示匹配com.savage.server.UserService中全部的公有方法 * 3)execution(* com.savage.server..*.*(..)) 表示匹配com.savage.server包及其子包下的全部方法 */ @Pointcut("execution(public * com.anole.manager.controller.RealTimeApiController.*(..))") public void auth() { } @Before("auth()") public void doBefore(JoinPoint joinPoint) { log.info("aop doBefore.."); ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //url log.info("url={}", request.getRequestURI()); //method log.info("method={}", request.getMethod()); //ip log.info("ip={}", request.getRemoteAddr()); //類方法 log.info("classMethod={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); //參數 Enumeration<String> paramter = request.getParameterNames(); while (paramter.hasMoreElements()) { String str = (String)paramter.nextElement(); log.info(str + "={}", request.getParameter(str)); } } @Around("auth()") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { StopWatch stopWatch = new StopWatch(); // 耗時計算-開始 stopWatch.start(); ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //參數 Enumeration<String> paramter = request.getParameterNames(); while (paramter.hasMoreElements()) { String str = (String)paramter.nextElement(); log.info(str + "={}", request.getParameter(str)); } // TODO 可在此處實現鑑權邏輯,修改返回response Object returnObj = proceedingJoinPoint.proceed(); // 耗時計算-結束 stopWatch.stop(); log.info("【{}方法】耗時:{}", proceedingJoinPoint.getSignature().getName(), stopWatch.getTotalTimeMillis()); return returnObj; } @After("auth()") public void doAfter() { log.info("aop doAfter"); } }