• Spring aop 记录操作日志 Aspect


    已于2018年01月04日更新了一个优化版,里面附带源码,地址为:http://www.cnblogs.com/leifei/p/8194644.html )

    前几天做系统日志记录的功能,一个操作调一次记录方法,每次还得去收集参数等等,太尼玛烦了。在程序员的世界里,当你的一个功能重复出现多次,就应该想想肯定有更简单的实现方法。于是果断搜索各种资料,终于搞定了,现在上代码

    环境: SpringMvc + myBatis

    jar包 :      (aspect.jar也行,我原来项目中有,便没有替换了)

    1.自定义注解类   ArchivesLog.java(获取Controller描述用的)

    package com.noahwm.uomp.archives.common;
    
    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.PARAMETER, ElementType.METHOD})  
    @Retention(RetentionPolicy.RUNTIME)  
    @Documented  
    public @interface ArchivesLog {
    
        /** 要执行的操作类型比如:add操作 **/  
        public String operationType() default "";  
    
        /** 要执行的具体操作比如:添加用户 **/  
        public String operationName() default ""; 
        
    }

    2.日志处理类  ArchivesLogAspect.java(业务处理)

    package com.noahwm.uomp.archives.common;
    import java.lang.reflect.Method;
    import java.text.SimpleDateFormat;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.log4j.Logger;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import com.noahwm.uomp.base.security.SecurityConstant;
    import com.noahwm.uomp.system.bo.User;
    
    public class ArchivesLogAspect {
        private final Logger logger = Logger.getLogger(this.getClass());  
    
        private String requestPath = null ; // 请求地址  
        private String userName = "" ; // 用户名  
        private Map<?,?> inputParamMap = null ; // 传入参数  
        private Map<String, Object> outputParamMap = null; // 存放输出结果  
        private long startTimeMillis = 0; // 开始时间  
        private long endTimeMillis = 0; // 结束时间  
        private User user = null;
        private HttpServletRequest request = null;
    
        /** 
         *  
         * @Description: 方法调用前触发   记录开始时间  
         * @author fei.lei  
         * @date 2016年11月23日 下午5:10 
         * @param joinPoint 
         */ 
        public void before(JoinPoint joinPoint){  
            //System.out.println("被拦截方法调用之后调用此方法,输出此语句");  
            request = getHttpServletRequest();  
            //fileName  为例子
            Object obj =request.getParameter("fileName");
            System.out.println("方法调用前: " + obj);
            user = (User)request.getSession().getAttribute(SecurityConstant.CURRENT_LOGIN_USER);
            startTimeMillis = System.currentTimeMillis(); //记录方法开始执行的时间  
        }  
        
        /** 
         *  
         * @Description: 方法调用后触发   记录结束时间  
         * @author fei.lei  
         * @date 2016年11月23日 下午5:10 
         * @param joinPoint 
         */
        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 operationName = "";
            for (Method method : methods) {  
                if (method.getName().equals(methodName)) {  
                    Class[] clazzs = method.getParameterTypes();  
                    if (clazzs!=null&&clazzs.length == arguments.length&&method.getAnnotation(ArchivesLog.class)!=null) {  
                        operationName = method.getAnnotation(ArchivesLog.class).operationName();
                        break;  
                    }  
                }  
            }
            endTimeMillis = System.currentTimeMillis();
            //格式化开始时间
            String startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTimeMillis);
            //格式化结束时间
            String endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endTimeMillis);
            
            Object obj =request.getParameter("fileName");
            System.out.println("方法调用后: " + obj);
            System.out.println(" 操作人: "+user.getName()+" 操作方法: "+operationName+" 操作开始时间: "+startTime +" 操作结束时间: "+endTime);
            
        }
        /**
         * @Description: 获取request  
         * @author fei.lei  
         * @date 2016年11月23日 下午5:10 
         * @param  
         * @return HttpServletRequest
         */
        public HttpServletRequest getHttpServletRequest(){
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();  
            ServletRequestAttributes sra = (ServletRequestAttributes)ra;  
            HttpServletRequest request = sra.getRequest();
            return request;
        }
      
        /** 
         *  
         * @Title:around 
         * @Description: 环绕触发  
         * @author fei.lei  
         * @date 2016年11月23日 下午5:10 
         * @param joinPoint 
         * @return Object
         * @throws Throwable 
         */  
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable {  
    
            return null;  
        }  
    
        /** 
         *  
         * @Title:printOptLog 
         * @Description: 输出日志  
         * @author fei.lei 
         * @date 2016年11月23日 下午5:10
         */  
        /*private void printOptLog() {  
            Gson gson = new Gson(); // 需要用到google的gson解析包  
            String startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTimeMillis);
            String endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endTimeMillis);  
            logger.info("user :" +user.getName()+ " start_time: " +  startTime +" end_time: "+endTime);  
        }  */
        
        
    }


    3.spring 注入

       
       

       <!--指定扫描目录-->
       <
    context:component-scan base-package="com.noahwm" /> <aop:aspectj-autoproxy proxy-target-class="true" /> <!--将日志类注入到bean中。--> <bean id="logAspect" class="com.noahwm.uomp.archives.common.ArchivesLogAspect"></bean> <aop:config> <!--调用日志类--> <aop:aspect id="LogAspect" ref="logAspect"> <!--配置在controller包下所有的类在调用之前都会被拦截--> <aop:pointcut id="log" expression="execution(* com.noahwm.uomp.archives.controller.*.*(..))"/> <!-- 方法前触发 --><aop:before pointcut-ref="log" method="before"/> <!-- 方法后触发 --><aop:after pointcut-ref="log" method="after"/> <!-- 环绕触发 <aop:around pointcut-ref="log" method="around"/> --> </aop:aspect> </aop:config>

    3.调用(设置Controller描述)

        @RequestMapping(value="/fileQuery")
        @ArchivesLog(operationType="查询操作:",operationName="查询文件") 
        public ModelAndView fileQuery(HttpServletRequest request,HttpServletResponse response){
    
            return new ModelAndView("archives/fileQuery");
           }    

    4.结果

    这样一来还可以记录操作前,操作后的值了

  • 相关阅读:
    winform 调用http 通过代理出现的一系列问题
    【转】 CSS3阴影 box-shadow的使用和技巧总结
    【转】 C#程序以管理员权限运行
    【转】WMI使用的WIN32_类库名
    【转】C#取硬盘、CPU、主板、网卡的序号 ManagementObjectSearcher
    【转】纯CSS设置Checkbox复选框控件的样式
    【转】vs2012 打包安装更改 setup.exe的图标
    【转】VS2012程序打包部署详解
    142. Linked List Cycle II
    141. Linked List Cycle
  • 原文地址:https://www.cnblogs.com/leifei/p/6094673.html
Copyright © 2020-2023  润新知