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.結果

這樣一來還可以記錄操作前,操作后的值了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM