springboot-spring aopシステム操作ログをデータベースに記録することを実現します。

21450 ワード

  • 参照が必要な依存性
  • <!--spring  aop  -->
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    
     application.properties          
    spring.aop.auto=true //                  
    
    application.yml      
    spring:
      aop:
        auto: true
    
  • ログを作成し、逆
  • を作成します。
    public class SysLog implements Serializable {
        private Long id;
    
        private String username; //   
    
        private String operation; //  
    
        private String method; //   
    
        private String params; //  
    
        private String ip; //ip  
    
        private Date createDate; //    
        //  getter setter  
    }
    
  • springのaop技術を使ってカスタム注釈に切るので、まずカスタム注釈クラス
  • を作成します。
    import java.lang.annotation.*;
    
    /**
     *       
     */
    @Target(ElementType.METHOD) //         ,METHOD          
    @Retention(RetentionPolicy.RUNTIME) //         
    @Documented //    
    public @interface MyLog {
        String value() default "";
    }
    
  • aopカット実現クラス
  • を作成します。
    import com.alibaba.fastjson.JSON;
    import com.qfedu.rongzaiboot.annotation.MyLog;
    import com.qfedu.rongzaiboot.entity.SysLog;
    import com.qfedu.rongzaiboot.service.SysLogService;
    import com.qfedu.rongzaiboot.utils.HttpContextUtils;
    import com.qfedu.rongzaiboot.utils.IPUtils;
    import com.qfedu.rongzaiboot.utils.ShiroUtils;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    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 javax.servlet.http.HttpServletRequest;
    import java.lang.reflect.Method;
    import java.util.Date;
    
    /**
     *     :     
     */
    @Aspect
    @Component
    public class SysLogAspect {
    
        @Autowired
        private SysLogService sysLogService;
    
        //     @Pointcut
        //          
        @Pointcut("@annotation( com.qfedu.rongzaiboot.annotation.MyLog)")
        public void logPoinCut() {
        }
    
        //       
        @AfterReturning("logPoinCut()")
        public void saveSysLog(JoinPoint joinPoint) {
            System.out.println("  。。。。。");
            //    
            SysLog sysLog = new SysLog();
    
            //                      
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            //          
            Method method = signature.getMethod();
    
            //    
            MyLog myLog = method.getAnnotation(MyLog.class);
            if (myLog != null) {
                String value = myLog.value();
                sysLog.setOperation(value);//       
            }
    
            //       
            String className = joinPoint.getTarget().getClass().getName();
            //        
            String methodName = method.getName();
            sysLog.setMethod(className + "." + methodName);
    
            //     
            Object[] args = joinPoint.getArgs();
            //           json
            String params = JSON.toJSONString(args);
            sysLog.setParams(params);
    
            sysLog.setCreateDate(new Date());
            //     
           //      ShiroUtils          ,      session        
           // :HttpSession session=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest().getSession();
    
            sysLog.setUsername(ShiroUtils.getUserEntity().getUsername());
            //    ip  
            HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
            sysLog.setIp(IPUtils.getIpAddr(request));
    
            //  service  SysLog       
            sysLogService.save(sysLog);
        }
    
    }
    
  • 続いて、監視が必要な方法にaopのカスタム注釈フォーマットを追加して@+カスタム注釈の類名@MyLog
  • とすることができる。
    //   contoller        
    @RestController
    @RequestMapping("/sys/menu")
    public class SysMenuController extends AbstractController {
    
        @Autowired
        private SysMenuService sysMenuService;
    
        @MyLog(value = "      ")  //     AOP      
        @PostMapping("/del")
        public R deleteBatch(@RequestBody Long[] menuIds) {
            for (Long menuId : menuIds) {
                if (menuId <= 31) {
                    return R.error("    ,    ");
                }
            }
            sysMenuService.deleteBatch(menuIds);
    
            return R.ok("    ");
        }
    }