SpringAOP + annotations for log management

1. What isAOP?

AOPAspect Orient Programming translates to Aspect oriented Programming. Object oriented Programming abstracts programs into multiple levels of objects, while Aspect Oriented Programming abstracts programs into multiple aspects

2. Why use itAOP(Scenario Description)

In time development, we use duplicate code in many modules, and we definitely don’t duplicate code by copying. Of course, there are many ways to solve this problem, usually we will take the repeated code and extract it into a method or abstract class. Then you just call this method where you need it. But as our business changes, the add method is removed and not needed, and we need to make separate removal of all the calls, which makes the job more difficult, AOP. The principle of AOP is the proxy pattern

3. Actual cases

Use AOP to complete log management

1. Log management data structure

CREATE TABLE `sys_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `operation` varchar(50) DEFAULT NULL COMMENT 'operation'.  `create_time` datetime DEFAULT NULL COMMENT 'Creation time'.  `method_name` varchar(100) DEFAULT NULL COMMENT 'Method name'. `param_name` varchar(500) DEFAULT NULL COMMENT 'parameters'. `ip` varchar(100) DEFAULT NULL COMMENT 'IP address'. `username` varchar(50) DEFAULT NULL COMMENT 'Username'. PRIMARY KEY (`id`),  UNIQUE KEY `id` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 Copy the code

Log table corresponding to the entity class, mapper, the service, the controller can be automatically generated by the mybatisplus, omit don’t write here.

2. Log management entry (code enhancement)

/ * * * @ClassName LoginLogAspect
 * @DescriptionOperation log entry * @Author xiongchao
 * @Date 2020/9/27 10:22 * * / @Aspect @Component public class SysLogAspect {   @Autowired  private ISysLogService logService;   @Autowired  private ApplicationProperties properties;   @Autowired  private JwtTokenUtil util;   // Define the Pointcut @pointcut  // Insert code at the point of comment  @Pointcut("@annotation( com.adingxiong.cft.aop.Mylog)")  public void logPoinCut(a) {   }   // Section configuration notification  @AfterReturning("logPoinCut()")  public void savaLog(JoinPoint joinpoin){   SysLog sysLog = new SysLog();   // The method of obtaining the point of entry from the section by reflection mechanism  MethodSignature signature = (MethodSignature) joinpoin.getSignature();  // Get the method where the pointcut resides  Method method = signature.getMethod();  Mylog myLog = method.getAnnotation(Mylog.class);   if(myLog ! =null) { String value = myLog.value();  sysLog.setOperation(value);  }   // Get the requested class name  String className = joinpoin.getTarget().getClass().getName();   // Get the requested method name  String methodName = method.getName();  sysLog.setMethodName(className + "." + methodName);   HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder  .getRequestAttributes()).getRequest();   String token = request.getHeader(properties.getTokenHeader());   String authToken = token.substring(properties.getTokenHead().length());  String username = util.getUserNameFromToken(authToken);   sysLog.setUsername(username);   String ip = IpUtils.getRealIp(request);  sysLog.setIp(ip);   // Request parameters  Object args [] = joinpoin.getArgs();  String param = JSON.toJSONString(args);  sysLog.setParamName(param);  sysLog.setCreateTime(new Date());  logService.save(sysLog);  }  }  Copy the code

3. GetIPThe utility class

/ * * * @ClassName IpUtils
 * @DescriptionObtain the real IP address of the user * @Author xiongchao
 * @Date2020/9/27 at 10:08* * / public class IpUtils {   public static String getRealIp(HttpServletRequest request) {  String ipAddress = request.getHeader("x-forwarded-for");  if(ipAddress == null || ipAddress.length() ==0 || "unknown".equals(ipAddress)){  ipAddress = request.getHeader("Proxy-Client-IP");  }  if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  ipAddress = request.getHeader("WL-Proxy-Client-IP");  }  if (StringUtils.isEmpty(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {  ipAddress = request.getHeader("HTTP_CLIENT_IP");  }  if (StringUtils.isEmpty(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {  ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");  }  if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {  ipAddress = request.getRemoteAddr();  if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) { // Obtain the local IP address based on the network adapter  InetAddress inet=null;  try {  inet = InetAddress.getLocalHost();  } catch (UnknownHostException e) {  e.printStackTrace();  }  ipAddress= inet.getHostAddress();  }  }  // In the case of multiple proxies, the first IP is the real IP of the client, and the multiple IP addresses are divided by ','  if(ipAddress! =null && ipAddress.length()>15) {//"***.***.***.***".length() = 15  if(ipAddress.indexOf(",") >0) { ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));  }  }  return ipAddress;  }  }  Copy the code

4. Custom annotations (using annotations to call aspect methods)

/ * * * @ClassName Mylog
 * @Description TODO
 * @Author xiongchao
 * @Date 2020/9/27 10:29 * * / @Target(ElementType.METHOD) METHOD is annotable at the METHOD level @Retention(RetentionPolicy.RUNTIME) // Specify in which phase to execute @Documented // Generate the document public @interface Mylog {  String value(a) default ""; } Copy the code

5. Test

Add @mylog (value=” XXXXX “) annotation to the Service or Controller layer to complete the call

    @Mylog(value = "Get current user information")
    @ApiOperation(value = "Obtain information about the currently logged in user")
    @GetMapping("/info")
    public Result<Map<String,Object>> getUserInfo(Principal principal){
        if(principal == null) { return Result.unauthorized(null);  }  String username = principal.getName();  TUser user = userService.getUserByUsername(username);  List<Role> list = roleService.getUserRole(user.getId());  Map<String,Object> res = new HashMap<>();  res.put("userInfo",user);  res.put("role",list);  return Result.success(res);  }  Copy the code

This article was typeset using MDNICE