天天看點

基于SpringBoot使用AOP切面使用注解實作使用者記錄檔管理

先介紹幾個注解

@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);
            }


        }
    }
 
    }
           

上面講解的不算太詳細是我本人所用的總結希望可以幫到你們。多看幾遍不難了解的