SpringAOP自定义注解日志

本文介绍如何使用Spring AOP自定义注解进行方法级别的日志记录,包括配置步骤、自定义注解创建、切面类实现及测试方法。通过在特定方法上使用自定义注解,可以自动记录方法调用的详细信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringAOP自定义注解日志

1.在SpringMVC.xml开启aop注解

<!-- aop面向切面编程 -->
<aop:aspectj-autoproxy proxy-target-class="true" />

2. 新建一个annotation类

package com.yc.util;

import java.lang.annotation.*;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * AOP自定义注解
 * @author lam
 * 2018年11月7日
 */
@Target({ElementType.METHOD})//方法
@Retention(RetentionPolicy.RUNTIME)//在运行时有效(即运行时保留)   
@Documented 
public @interface SystemControllerLog {
  /**
   * 日志描述
   * @return
   */
  String description()  default "";
}

3.新建一个SystemLogAspect类---可以实现对具体参数的记录(例子只是获取单个字段,因为项目关系,查集合就不需要记录到具体参数,查询单个就可以记录到具体参数),还可以实现对不加(@SystemControllerLog)注解的不记录

package com.yc.action;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.yc.model.Log;
import com.yc.service.LogService;
import com.yc.util.SystemControllerLog;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Date;
import java.util.Enumeration;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 日志切面
 *
 * @author lam
 * @create 2018年11月7日
 **/
@Aspect
@Component
public class SystemLogAspect {
  @Resource
  private LogService logService;
	
  //Controller层切点(AspectJ的execution表达式)
  @Pointcut("execution(* com.yc.action..*.*(..))")
  public void controllerAspect() {}
    
  @After("controllerAspect()")
  public void controllerAspect(JoinPoint joinPoint) throws Exception{
	  HttpServletRequest request =
		        ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	  // 请求的IP
	  String ip = request.getHeader("x-forwarded-for");
	  if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
	    // 多次反向代理后会有多个ip值,第一个ip才是真实ip
	    if (ip.indexOf(",") != -1) {
	       ip = ip.split(",")[0];
	    }
	  }
	  if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
	     ip = request.getHeader("Proxy-Client-IP");
	  }
	  if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
	     ip = request.getHeader("WL-Proxy-Client-IP");
	  }
	  if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
	     ip = request.getHeader("HTTP_CLIENT_IP");
	  }
	  if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
	     ip = request.getHeader("HTTP_X_FORWARDED_FOR");
	  }
	  if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
	     ip = request.getHeader("X-Real-IP");
	  }
	  if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
	     ip = request.getRemoteAddr();
	  }
	  // 获取本地ip地址
	  if (ip.equals("127.0.0.1")) {
	    // 根据网卡取本机配置的IP
	    InetAddress inet = null;
	    @SuppressWarnings("rawtypes")
	    Enumeration allNetInterfaces = null;
	    try {
	      allNetInterfaces = NetworkInterface.getNetworkInterfaces();
	    } catch (java.net.SocketException e) {
	      e.printStackTrace();
	    }
	    while (allNetInterfaces.hasMoreElements()) {
	      NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
	      @SuppressWarnings("rawtypes")
	      Enumeration addresses = netInterface.getInetAddresses();
	      while (addresses.hasMoreElements()) {
	         inet = (InetAddress) addresses.nextElement();
	         if (inet != null && inet instanceof Inet4Address) {
	           if (inet.getHostAddress().equals("127.0.0.1")) {
	             continue;
	           }
	           ip = inet.getHostAddress();
	        }
	      }
	    }
	  }
	  //日志
      Log log =new Log();
      log.setIp(ip);
      log.setDate(new Date());
      //log.setName("test");//获取用户id
      //log.setCompanyId(99);//获取用户公司id
	  //获取参数
	  Object[] arguments = joinPoint.getArgs();
	  String params = JSON.toJSONString(arguments); 
	  JSONArray json = JSONArray.parseArray(params);//转换为json数组,可获取具体的字段
	  String isNull= null;
	  if(params.indexOf("companyName") != -1) {
		  for(int i=0;i < json.size();i++) {
			  isNull= json.getJSONObject(i).getString("companyName");
			  break;
		  }
	  }else {
	  }
      //判断是否记录单个参数
	  if (isNull !=null) {
		 //判断是否切面(是否加SystemControllerLog注解)
		 if(getControllerMethodDescription(joinPoint) !=null) {
			log.setOperation(getControllerMethodDescription(joinPoint)+"--"+isNull);//带参数(对单个参数增删改生效)
		 }else {
			 return;
		 }
	  }else {
		//判断是否切面(是否加SystemControllerLog注解)
		if(getControllerMethodDescription(joinPoint) !=null) {
			log.setOperation(getControllerMethodDescription(joinPoint));//不带参(查询等等)
		}else {
			return;
		}
	  }
	  int len =logService.insert(log);
  }
  
  //获取方法
  @SuppressWarnings("rawtypes")
  public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
	String targetName = joinPoint.getTarget().getClass().getName(); // 获取切入目标的类名
    String methodName = joinPoint.getSignature().getName();// 获取切面切入目标的方法名
    Object[] arguments = joinPoint.getArgs(); // 获取切入方法的所有参数
    Class targetClass = Class.forName(targetName); // 通过类名找到类对象
    Method[] methods = targetClass.getMethods(); // 获取类对象的所有方法
    String description = "";
    for (Method method : methods) {
    	if (method.getName().equals(methodName)) { // 比较方法名相同
        Class[] clazzs = method.getParameterTypes();
        // 参数长度
        if (clazzs.length == arguments.length) {
        	//判断是否切面(是否加SystemControllerLog注解)
        	if(method.getAnnotation(SystemControllerLog.class) !=null) {
        		description = method.getAnnotation(SystemControllerLog.class).description();
                break;
        	}else {
				return null;
			}
          }
       }
    }
   return description;
  }
}

4.新建测试类(不加注解没有记录)

  /**
   * 测试带参数
   * @param company
   * @return
   */
  @ResponseBody
  @RequestMapping("test.do")
  @SystemControllerLog(description="测试带参数")
  public JSONObject test(CustomerCompany company) {
	  JSONObject jsonObject =new JSONObject();
	  return jsonObject;
  }
  
  /**
   * 测试不带参数
   * @return
   */
  @ResponseBody
  @RequestMapping("test1.do")
  @SystemControllerLog(description="测试不带参数")
  public JSONObject test1() {
	  JSONObject jsonObject =new JSONObject();
	  return jsonObject;
  }

5.运行效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值