springAOP注解方式實現日志操作


通過自定義注解調用方法執行日志存儲:

package com.zktx.platform.log2;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.zktx.platform.entity.tb.logInfo;
import com.zktx.platform.entity.tb.user.ShiroUser;
import com.zktx.platform.service.log.LogService;
import com.zktx.platform.shiro.SecurityUtils;

/**
 * * 首先我們為什么需要做日志管理,在現實的上線中我們經常會遇到系統出現異常或者問題。 這個時候就馬上打開CRT或者SSH連上服務器拿日子來分析。
 * 受網絡的各種限制。於是我們就想為什么不能直接在管理后台查看報錯的信息呢。於是日志管理就出現了。
 * 其次個人覺得做日志管理最好的是Aop,有的人也喜歡用攔截器。都可以,在此我重點介紹我的實現方式。 Aop有的人說攔截不到Controller。
 * 有的人說想攔AnnotationMethodHandlerAdapter截到Controller必須得攔截org
 * .springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter。
 * 首先Aop可以攔截到Controller的
 * ,這個是毋容置疑的其次須攔截AnnotationMethodHandlerAdapter也不是必須的。最起碼我沒有驗證成功過這個
 * 。我的Spring版本是4.0.3。
 * Aop之所以有的人說攔截不到Controller是因為Controller被jdk代理了。我們只要把它交給cglib代理就可以了
 * 
 * <!-- 啟動對@AspectJ注解的支持 --> <aop:aspectj-autoproxy />
 * <!--通知spring使用cglib而不是jdk的來生成代理方法 AOP可以攔截到Controller-->
 * <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
 * <!-- 節點中proxy-target-class="true"不為true時。 *
 * 當登錄的時候會報這個異常java.lang.NoSuchMethodException: $Proxy54.login(), -->
 * <aop:config proxy-target-class="true"></aop:config>
 * 
 * 創建一個切點類
 * 
 * @author Administrator
 *
 */
@Aspect
@Component
public class SystemLogAspect {

    // 本地異常日志記錄對象
    private static final Logger log = LoggerFactory.getLogger(SystemLogAspect.class);

    @Autowired
    LogService logService;

    @Autowired
    private HttpServletRequest request;

    // Controller層切點
    @Pointcut("@annotation(com.zktx.platform.log2.SystemControllerLog)")
    public void controllerAspect() {
    }

    @After(value = "controllerAspect()")
    public void doAfter(JoinPoint joinPoint) {
        // 這里獲取request;千萬不要寫在下邊的線程里,因為得不到
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        System.out.println(request.getAttribute("message") + "=======");

        new Thread(new Runnable() {

            @Override
            public void run() {
                try {

                    // log.info("進入日志系統————————————" + request.getLocalAddr());
                    logInfo info = new logInfo();
                    String description = getControllerMethodDescription(joinPoint);
                    ShiroUser user = SecurityUtils.getShiroUser();

                    info.setUser_name(user.getName());
                    info.setMessage(description);
                    info.setIp_address(user.getIpAddress());
                    info.setCreate_time(new Date());
                    logService.insertLogInfo(info);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    // 可以得到方法return的值
    @AfterReturning(returning = "ret", pointcut = "controllerAspect()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 處理完請求,返回內容
        System.out.println(ret);
        Map<String, Object> map = (Map<String, Object>) ret;
        System.out.println(map.get("total"));
    }

    // 通過反射獲取參入的參數
    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);
        String description = "";

        Method[] methods = targetClass.getMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();

                if (clazzs.length == arguments.length) {
                    description = method.getAnnotation(SystemControllerLog.class).description();
                    break;
                }
            }
        }
        return description;
    }
}

 

定義注解:

package com.zktx.platform.log2;

/**
 * 自定義注解,攔截Controller
 */
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;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.PARAMETER })
@Documented
public @interface SystemControllerLog {
    String description() default "";
}

使用方式:

// 條件查詢
    @SystemControllerLog(description = "查詢導入表")
    @RequestMapping("/query")
    public @ResponseBody Map<String, Object> findByPagination(ImportTablesPo tablesPo) {
        log.info("導入表查詢————————");
        try {
            int count = tableService.findCountByParms(tablesPo);
            List<ImportTablesWithBLOBs> list = tableService.findByPagination(tablesPo);
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("total", count);
            map.put("rows", list);
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

 


免責聲明!

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



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