spring aop实现操作日志记录

硅谷探秘者 2247 0 0

spring aop实现操作日志记录

        此次的目的是实现 对 controller中的方法执行情况进行记录,记录的有方法执行时间,操作人,请求的路径,方法的入参,模块,功能等。并实现利用注解的方式实现对被操作方法的简单注释(模块,功能)

        框架 springmvc+ mybatis

1.Log注解

package com.dzqc.dz.common.aop;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
    /** 方法模块 */
    String title() default "";
    /** 功能 */
    String action() default "";
}

2.LogAspect切面 (重点)

package com.dzqc.dz.common.aop;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.dzqc.dz.common.dao.LogMapper;
import com.dzqc.dz.common.entity.LogMessage;
/**
 * @author Administrator
 * @Description 日志记录
 */
public class LogAspect {
	@Autowired
	private LogMapper logMapper;//日志 mapper
	
    private String requestPath = null ; // 请求地址  
    private long startTimeMillis = 0; // 开始时间  
    private long endTimeMillis = 0; // 结束时间  
    private String user = null; // 操作人
    private HttpServletRequest request = null;//请求
   /**
    * @param joinPoint
    * @Description 气质通知  方法调用前触发   记录开始时间,从session中获取操作人
    */
    public void before(JoinPoint joinPoint){  
        startTimeMillis = System.currentTimeMillis(); 
    } 
    /**
     * @param joinPoint
     * @Description 获取入参方法参数
     * @return
     */
    public Map<String, Object> getNameAndValue(JoinPoint joinPoint) {
        Map<String, Object> param = new HashMap<>();
        Object[] paramValues = joinPoint.getArgs();
        String[] paramNames = ((CodeSignature)joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < paramNames.length; i++) {
        	if(paramValues[i] instanceof Integer || paramValues[i] instanceof String) {
        		param.put(paramNames[i], paramValues[i]);
        	}
        }
        return param;
    }
    /**
     * @param joinPoint
     * @Description 后置通知    方法调用后触发   记录结束时间 ,操作人 ,入参等
     */
    public void after(JoinPoint joinPoint) {
        request = getHttpServletRequest();
        String targetName = joinPoint.getTarget().getClass().getName();  
        String methodName = joinPoint.getSignature().getName();  
        Object[] arguments = joinPoint.getArgs();  
        Class<?> targetClass = null;
        try {
            targetClass = Class.forName(targetName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method[] methods = targetClass.getMethods();
        String title;
        String action;
        Class<?>[] clazzs;
        for (Method method : methods) {  
            if (method.getName().equals(methodName)) {  
            	clazzs = method.getParameterTypes();  
                if (clazzs!=null&&clazzs.length == arguments.length
                &&method.getAnnotation(Log.class)!=null) {  
                	request = getHttpServletRequest();
                    requestPath=request.getServletPath();
                    user = (String) request.getSession().getAttribute("user");
                    title = method.getAnnotation(Log.class).title();
                    action = method.getAnnotation(Log.class).action();
                    endTimeMillis = System.currentTimeMillis();
                    LogMessage log=new LogMessage(user, requestPath, 
                    (endTimeMillis-startTimeMillis)+"ms", 
                    getNameAndValue(joinPoint).toString(), title, action);
                    logMapper.writeLog(log);
                    break;  
                }  
            }  
        }
    }
    /**
     * @Description: 获取request  
     */
    public HttpServletRequest getHttpServletRequest(){
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();  
        ServletRequestAttributes sra = (ServletRequestAttributes)ra;  
        HttpServletRequest request = sra.getRequest();
        return request;
    }
    /**
     * @param joinPoint
     * @return 环绕通知
     * @throws Throwable
     */
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {  
        return null;  
    }  
    /**
     * @param joinPoint
     * @Description 异常通知
     */
    public void throwing(JoinPoint joinPoint) {
    	System.out.println("异常通知");
    }
}

3.封装日志信息的实体类

package com.dzqc.dz.common.entity;

public class LogMessage {
	private String operationUser;//操作人
	private String path;//请求路径
	private String time;//方法执行时间
	private String parameter;//方法入参
	private String title;//操作方法
	private String action;//方法描述
	public String getOperationUser() {
		return operationUser;
	}
	public LogMessage() {
		super();
		// TODO Auto-generated constructor stub
	}
	public LogMessage(String operationUser, String path, String time, 
	String parameter, String title, String action) {
		super();
		this.operationUser = operationUser;
		this.path = path;
		this.time = time;
		this.parameter = parameter;
		this.title = title;
		this.action = action;
	}
	public void setOperationUser(String operationUser) {
		this.operationUser = operationUser;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public String getTime() {
		return time;
	}
	public void setTime(String time) {
		this.time = time;
	}
	public String getParameter() {
		return parameter;
	}
	public void setParameter(String parameter) {
		this.parameter = parameter;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getAction() {
		return action;
	}
	public void setAction(String action) {
		this.action = action;
	}
	
}

4.Mapper

package com.dzqc.dz.common.dao;

import com.dzqc.dz.common.entity.LogMessage;
public interface LogMapper {
	public void writeLog(LogMessage message);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.dzqc.dz.common.dao.LogMapper" >
  <insert id="writeLog" parameterType="com.dzqc.dz.common.entity.LogMessage">
  	INSERT into log(operationUser,path,time,parameter,title,action) VALUES(#{operationUser},#{path},#{time},#{parameter},#{title},#{action});
  </insert>
</mapper>

5.spring aop配置文件

    <aop:aspectj-autoproxy proxy-target-class="true" />
    
    <!--将日志类注入到bean中。-->
    <bean id="logAspect" class="com.dzqc.dz.common.aop.LogAspect"></bean>   
    
    <aop:config>
          <aop:aspect id="LogAspect" ref="logAspect">
              <aop:pointcut id="log" expression="execution(* com.dzqc.dz.*.controller.*.*(..))"/>  
              <aop:before pointcut-ref="log" method="before"/> 
              <aop:after-throwing pointcut-ref="log" method="throwing" throwing="e"/>
              <aop:after pointcut-ref="log" method="after"/>
          </aop:aspect>
    </aop:config>


6.测试controller

package com.dzqc.dz.common.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.dzqc.dz.common.aop.Log;

@Controller
@RequestMapping("/test")
public class TestController {
	
	@RequestMapping("/logtest")
	@ResponseBody
	@Log(title="logtest",action="测试log日志")
	public Map<String,Object> logtest(HttpSession session,Integer id,String username) {
		session.setAttribute("user","jiajiajia");
		Map<String,Object> map=new HashMap<>();
		map.put("code", 200);
		map.put("data", "success");
		return map;
	}
	
	@RequestMapping("/test")
	@ResponseBody
	public Map<String,Object> test(HttpSession session,Integer id,String username) {
		session.setAttribute("user","jiajiajia");
		Map<String,Object> map=new HashMap<>();
		map.put("code", 200);
		map.put("data", "success");
		return map;
	}
}


        我们在logtest方法中加入Log注解,在调用这个方法的时候 会把一些信息记录进数据库,而没有加Log注解的方法则没有记录,但是根据aop的配置可知,TestController中所有的方法都被植入进了 LogAspect 切面中的逻辑,只是在LogAspect中进行了判断,只有带Log注解的方法执行才会 被记录进数据库。


测试

menu.saveimg.savepath20190227171318.jpg


注意:如果运行出现如下错误,请换较高版本的spring依赖

menu.saveimg.savepath20190228140816.jpg

<spring.version>4.3.5.RELEASE</spring.version>

    4.3.5版本的不会报错

猜你喜欢
spring/springmvc 70 "spring在ioc容器中获取aop的受理对象",这句话是什么意思呢?有时候我们会在spring项目中对一下类进行代理,比如我们会用springaop和自定义注解对一些接口访问添加,再比如对
框架 226 1.Log注解importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;//
spring/springmvc 515 bean的什么周期SpringBean的生命周期在整个Spring中占有很重要的位置,从BeanFactory或ApplicationContext取得的例为Singleton,也就是预设为每一个
spring/springmvc 1463 目接着就开始配置spring,springmvc,mybatis等1.首先目结构如下因为上次没有在model-web模块中添加对model-common的依赖,所以这次我们在model-web的pom
spring/springmvc 895 搭建spring+springmvc+mybatis+maven项目(1)首先在配置好maven仓库的情况下:1.创建父项目file-new-mavenprojectnextgroup为父项目坐标
框架 1390 1.项目结构2.pom文件依赖?xmlversion="1.0"encoding="UTF-8"?projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.
框架 3160 上次我们说了spring集成websocket,用websocket通讯集成配置连接:http://www.jiajiajia.club/weblog/blog/artical/128下面来模拟
框架 1055 如果你的eclipse安装了springboot插件可以通过下面方式1.选择springboot项目右击选择spring-adddevtools2.点击后pom文件中会出一个依赖
归档
2018年11月  12 2018年12月  33 2019年01月  28 2019年02月  28 2019年03月  32 2019年04月  27 2019年05月  33 2019年06月  6 2019年07月  12 2019年08月  12 2019年09月  21 2019年10月  8 2019年11月  15 2019年12月  25 2020年01月  9 2020年02月  5 2020年03月  16 2020年04月  4 2020年06月  1 2020年07月  7 2020年08月  13 2020年09月  9 2020年10月  4
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git undefined undefined sdf sdf dsdf sdfasdfasd sdf ppp sdf fggdgsd kkk kkk kkk sdddf 456
目录