先介紹幾個注解
@Aspect //代表這個類是一個切面
@Component //代表這個類被Spring所管理
@Before //這個代表前置通知運作方法前攔截運作有這個注解的方法
@After //這個代表後置通知運作方法後傳回攔截運作有這個注解的方法
下面開始講解使用方法
首先添加Spring-boot的AOP jar包
<!-- aop依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
接下來開始使用
先建立一個類名字随意
@Aspect //這個是個切面
@Component //被Spring-boot所管理
@Slf4j
public class SystemLogAspect {
}
建立一個方法
@Aspect
@Component
@Slf4j
public class SystemLogAspect {
// 後置通知:在目标方法運作之後運作
// value的值代表切入點
@After(value = "execution(* com.bjhz.api.controller..*.*(..))")
public void doBefore(JoinPoint joinpoint) throws Throwable {
}
首先自定義一個注解
//注解的名字就是方法名比如下面的注解就叫@Menu
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Menu {
String value() default "";
}
//這個方法是擷取注解的值 傳回值和注解的方法名相同
public static Menu getMenu(Method method) {
if (method != null) {
return method.getAnnotation(Menu.class);
}
return null;
}
//這個方法用于從攔截的接口中擷取注解
public static Method getMethod(JoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method;
}
return null;
}
接下來看我們切入點所攔截的方法
//注解的值代表這個方法的操作用于登記資料庫
@Menu("系統管理-審計日志")
@GetMapping("/selectlist")
@ResponseBody
public JSONObject selectoperLog(Map<String, Object> param) {
return operLogService.selectoperLog(param);
}
接下來編寫我們的切入點方法
@Aspect
@Component
@Slf4j
public class SystemLogAspect {
//用于存儲資料庫的接口
@Autowired
private TOperLogMapper operLogMapper;
// 後置通知:在目标方法運作之後運作
@After(value = "execution(* com.bjhz.api.controller..*.*(..))")
public void doBefore(JoinPoint joinpoint) throws Throwable {
// 獲得注解
//此方法的作用看上面的介紹
Method method = WebLogUtil.getMethod(joinpoint);
//這個方法是取注解
Menu Menu = WebLogUtil.getMenu(method);
//判斷注解是否存在
if (Menu!=null) {
System.out.println("攔截到了請求");
//攔截到請求
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//擷取請求
HttpServletRequest request = attributes.getRequest();
//擷取響應
HttpServletResponse response = attributes.getResponse();
//擷取是否執行成功狀态嗎
int status = response.getStatus();
//從請求中擷取Header中存儲的Token令牌
String header = request.getHeader("X-Token");
//解析Token令牌
Map<String, Object> valid = JwtTokenUtils.valid(header);
String data = String.valueOf(valid.get("data"));
JSONObject jsonObject = JSONObject.parseObject(data);
//擷取使用者名
String username = jsonObject.getString("username");
//擷取使用者名Id
String userId = jsonObject.getString("userid");
//記錄請求内容
log.info("userId:{}", userId);
log.info("username:{}", username);
log.info("URL : " + request.getRequestURL().toString());
log.info("HTTP_METHOD : " + request.getMethod());
log.info("IP : " + request.getRemoteAddr());
String Menus = Menu.value();
if (StringUtil.isNotNull(MenuTypes) && StringUtil.isNotNull(Menus)) {
TOperLog operLog = new TOperLog();
operLog.setId(UUID.randomUUID().toString().replace("-", ""));
operLog.setOperUserId(userId);
operLog.setOperUserName(username);
operLog.setOperDt(new Date());
operLog.setOperUrl(request.getRequestURL().toString());
operLog.setOperUserIp(request.getRemoteAddr());
operLog.setOperMethod(request.getMethod());
operLog.setOperMenuName(split[0]);
operLog.setOperOperationType(MenuTypes);
operLog.setOperOperationContent(MenuType.value() + Menu.value());
if (status!=200){
operLog.setOperOperationData("失敗");
}else {
operLog.setOperOperationData("成功");
}
//存儲操作
operLogMapper.insertSelective(operLog);
}
}
}
}