首页 > 代码库 > spring Aspect 实现自定义注解的日志记录

spring Aspect 实现自定义注解的日志记录

由于直接拦截所有的controller所以需要spring.xml中添加
<aop:aspectj-autoproxy proxy-target-class="true" />  交由cglib代理。

使用只要在controller的method上加上
@ActionControllerLog(channel="web",action="user_register",title="用户注册",isSaveRequestData=http://www.mamicode.com/true)
其中isSavveRequestData代表是否保存请求参数,默认为false。

  1 import java.lang.reflect.Method;
  2 import java.util.Date;
  3 import java.util.Map;
  4  
  5 import javax.annotation.Resource;
  6 import javax.servlet.http.HttpServletRequest;
  7  
  8 import org.aspectj.lang.JoinPoint;
  9 import org.aspectj.lang.Signature;
 10 import org.aspectj.lang.annotation.AfterReturning;
 11 import org.aspectj.lang.annotation.AfterThrowing;
 12 import org.aspectj.lang.annotation.Aspect;
 13 import org.aspectj.lang.annotation.Pointcut;
 14 import org.aspectj.lang.reflect.MethodSignature;
 15 import org.slf4j.Logger;
 16 import org.slf4j.LoggerFactory;
 17 import org.springframework.stereotype.Component;
 18 import org.springframework.web.context.request.RequestContextHolder;
 19 import org.springframework.web.context.request.ServletRequestAttributes;
 20  
 21 import com.alibaba.fastjson.JSONObject;
 22 import com.dlodlo.model.BusUserModel;
 23 import com.dlodlo.model.BusUserlogModel;
 24 import com.dlodlo.service.BusUserlogService;
 25  
 26 @Aspect
 27 @Component
 28 public  class SystemLogAspect {
 29     //注入Service用于把日志保存数据库    
 30     @Resource   
 31     private BusUserlogService busUserlogService;
 32     //本地异常日志记录对象    
 33     private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);
 34      
 35     //Controller层切点
 36     @Pointcut("@annotation(com.dlodlo.util.ActionControllerLog)")
 37     public  void controllerAspect() {
 38     }    
 39      
 40     /**  
 41      * 前置通知 用于拦截Controller层记录用户的操作 
 42      *
 43      * @param joinPoint 切点
 44      */
 45     @AfterReturning(pointcut="controllerAspect()")
 46     public  void doBefore(JoinPoint joinPoint) {
 47         handleLog(joinPoint,null);
 48     }
 49      
 50      
 51 //    @AfterReturning(pointcut="controllerAspect()",argNames = "joinPoint,retVal",returning = "retVal")
 52     @AfterThrowing(value="http://www.mamicode.com/controllerAspect()",throwing="e")
 53     public void doAfter(JoinPoint joinPoint,Exception e)
 54     {
 55         handleLog(joinPoint,e);
 56     }
 57  
 58 private void handleLog(JoinPoint joinPoint,Exception e) {
 59     try {
 60         //获得注解
 61         ActionControllerLog controllerLog = giveController(joinPoint);
 62         if(controllerLog == null)
 63         {
 64             return;
 65         }
 66         //获取当前的用户
 67         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
 68         BusUserModel userModel = (BusUserModel) SessionUtil.getAttrAsObject(request, SessionUtil.SESSION_USER);
 69          
 70         //*========数据库日志=========*//    
 71         BusUserlogModel userlogModel = new BusUserlogModel();
 72         //请求的IP
 73         String ip = MethodUtil.getIpAddr(request);
 74         userlogModel.setUserIp(ip);
 75         userlogModel.setCreateTIme(new Date());
 76         userlogModel.setUrl(request.getRequestURI());
 77         if(userModel != null)
 78         {
 79             userlogModel.setUserId(userModel.getId().longValue());
 80             userlogModel.setUserName(userModel.getUserName());
 81         }
 82          
 83         if(e != null)
 84             userlogModel.setErrorMessage(e.getMessage());
 85          
 86         //处理设置注解上的参数
 87         getControllerMethodDescription(controllerLog,userlogModel,request);
 88         //保存数据库
 89         busUserlogService.insert(userlogModel);
 90       }  catch (Exception exp) {
 91        //记录本地异常日志
 92        logger.error("==前置通知异常==");
 93        logger.error("异常信息:{}", exp.getMessage());
 94        exp.printStackTrace();
 95       }
 96 }
 97      
 98     /**  
 99      * 获取注解中对方法的描述信息 用于Controller层注解
100      *  
101      * @param joinPoint 切点
102      * @return 方法描述
103      * @throws Exception
104      */   
105      public  static void getControllerMethodDescription(ActionControllerLog controllerLog,BusUserlogModel userlogModel,HttpServletRequest request)  throws Exception { 
106         //设置action动作
107         userlogModel.setAction(controllerLog.action());
108         //设置标题
109         userlogModel.setTitle(controllerLog.title());
110         //设置channel
111         userlogModel.setChannel(controllerLog.channel());
112         //是否需要保存request,参数和值
113         if(controllerLog.isSaveRequestData())
114         {
115             //获取参数的信息,传入到数据库中。
116             setRequestValue(userlogModel,request);
117         }
118      }
119  
120      /**
121       * 获取请求的参数,放到log中
122       * @param userlogModel
123       * @param request
124       */
125     @SuppressWarnings("rawtypes")
126     private static void setRequestValue(BusUserlogModel userlogModel,HttpServletRequest request) {
127         if(userlogModel == null)
128             userlogModel = new BusUserlogModel();
129         Map map = request.getParameterMap();
130         String params = JSONObject.toJSONString(map);
131         userlogModel.setRequestParam(params);
132     }
133      
134     /**
135      * 是否存在注解,如果存在就记录日志
136      * @param joinPoint
137      * @param controllerLog
138      * @return
139      * @throws Exception
140      */
141     private static ActionControllerLog giveController(JoinPoint joinPoint) throws Exception
142     {
143         Signature signature = joinPoint.getSignature();
144         MethodSignature methodSignature = (MethodSignature) signature;  
145         Method method = methodSignature.getMethod();  
146          
147         if(method != null)
148         {
149             return method.getAnnotation(ActionControllerLog.class);
150         }
151         return null;
152     }
153 }

 

注解类

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
 
@Target({ElementType.PARAMETER, ElementType.METHOD})    
@Retention(RetentionPolicy.RUNTIME)    
@Documented   
public @interface ActionControllerLog {
    /** 标题 */
    String title()  default "";
    /** 动作的名称 */
    String action() default "";
    /** 是否保存请求的参数 */
    boolean isSaveRequestData() default false;
    /** 渠道 */
    String channel() default "web";
}

 

spring Aspect 实现自定义注解的日志记录