1. 程式人生 > >Spring AOP 自定義註解記錄操作日誌

Spring AOP 自定義註解記錄操作日誌

1.自定義註釋

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Log {
    LogType type() default LogType.SPACE;
}
2.type值的列舉
public enum LogType {
    SPACE(""),
    INSERT("增加"),
    DELETE("刪除"),
    UPDATE("修改"),
    QUERY("查詢");

     private String description;
     private LogType( String string) {
         description=string;
    }

    public String GetDescription()
    {
        return description;
    }
}
3.註釋的使用
public abstract class AbstractService<T, M> implements IService<T, M>
{
    @Override
    @Log(type = LogType.INSERT)
    public int add(T t)
    {
        return getMapper().insert(t);
    }}

4.自定義切面(注意@Aspect 和@Component註解)
@Aspect
@Component
public class OperateLogAspect {

    @Autowired
    private IOperationLogService operationLogService;

    /**
     * 後置增強
     */
    @After("@annotation(cn.com.reformer.annotation.Log) && @annotation(log)")
    private void after(JoinPoint joinPoint, Log log) {
        //讀取中的使用者
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Admin user = (Admin) request.getAttribute(Constants.CURRENT_ADMIN);
        //未登入或登入操作
        if (null == user) {
            return;
        }
        //沒有引數
        if (joinPoint.getArgs() == null) {
            return;
        }
        OperationLog operationLog = new OperationLog();
        operationLog.setUserId(user.getId());
        operationLog.setIpAddr(getIP(request));
        operationLog.setOpearteTime(new Date());
        Object[] os = joinPoint.getArgs();
        //獲取類名
        String className = joinPoint.getTarget().getClass().getSimpleName();
        //獲取方法名
        String methodName = joinPoint.getSignature().getName();
        String param = className + "." + methodName + ":";
        for (int i = 0; i < os.length; i++) {
            param += "引數[" + i + "]:" + os[i].toString();
        }
        operationLog.setOperation(log.type().GetDescription());
        operationLog.setOperateContent(param);
        //寫入資料庫
        operationLogService.insertSelective(operationLog);
        return;
    }

    //獲取請求IP
    public String getIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
</pre><p></p><pre>
5.配置Spring-mvc.xml

proxy-target-class="true"為開啟CGLIB動態代理

    <!--自定義切面所在包-->
    <context:component-scan base-package="cn.com.reformer.service"/>
    <!--識別切面,開啟CGLIB動態代理-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
6.此過程中遇到的麻煩

在資料庫寫操作日誌時報read-only的錯誤,原因事務配置了read-only,如下:

    <!-- 事務管理 通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 對insert,update,delete 開頭的方法進行事務管理,只要有異常就回滾 -->
            <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="create*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <!-- select,count開頭的方法,開啟只讀,提高資料庫訪問效能 -->
            <tx:method name="select*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="count*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <!-- 對其他方法 使用預設的事務管理 -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
解決方法:

      1.此處設定read-only的地方全部都是查詢,可以不記錄查詢日誌,及查詢方法前不加自定義註解@Log

      2.去掉事務的read-only屬性

相關推薦

Spring AOP 定義註解記錄操作日誌

1.自定義註釋 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface Log { LogType type() default Lo

Spring AOP定義註解實現系統日誌記錄管理

package com.kilomob.powernetwork.managerweb.annotation; import java.lang.reflect.Method; import java.net.InetAddress; import java.util.Arrays; import java

使用Spring AOP定義註解方式實現使用者操作日誌記錄

1,開發環境 作業系統:Windows 7 JDK:1.8.0_161 Eclipse:Mars.2 Release (4.5.2) 2,自定義註解類UserLog @Target({ElementType.PARAMETER, ElementType.METHOD}) @R

Spring/Springboot AOP 定義註解記錄日誌操作

本文采用的方法是使用註解記錄日誌,廢話不多說直接上乾貨。 建立一個自定義@Log日誌標籤 package com.insurance.dao; import java.lang.annotation.Documented; import java.lang.ann

使用Spring Aop定義註解實現自動記錄日誌

百度加自己琢磨,以下親測有效,所以寫下來記錄,也方便自己回顧瀏覽加深印象之類,有什麼問題可以評論一起解決,不完整之處也請大佬指正,一起進步哈哈(1)首先配置檔案: <!-- 宣告自動為spring容器中配置@aspectj切面的bean建立代理 ,織入切面 --> <aop:

Spring aop+定義註解統一記錄使用者行為日誌

Spring aop+自定義註解統一記錄使用者行為日誌 原創: zhangshaolin 張少林同學 今天 寫在前面 本文不涉及過多的Spring aop基本概念以及基本用法介紹,以實際場景使用為主。 場景 我們通常有這樣一個需求:列印後臺介面

Spring AOP 定義註解實現日誌管理

目錄 一、配置檔案 二、新建一個日誌實體類Log 三、編寫 service 層 四、編寫 service 層的實現 serviceimpl 五、自定義註解類 六、編寫切面類 七、spring + aop 需要的 jar 包 部落格的程式碼是基於 SSM 環境編寫的

spring-AOP+定義註解實現日誌管理(註解方式實現)

一、場景 後臺管理系統中,管理員作業系統時生成日誌儲存在資料庫中。 二、實現 1、jar包依賴 <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency&

利用Spring AOP定義註解解決日誌和簽名校驗

一、需解決的問題 部分API有簽名引數(signature),Passport首先對簽名進行校驗,校驗通過才會執行實現方法。     第一種實現方式(Origin):在需要簽名校驗的接口裡寫校驗的程式碼,例如: boolean isValid = accountService.val

Spring AOP 定義註解檢查請求頭(示例)

程式碼傳送門 需求 一個 Controller 可以處理 HTTP 請求 @RestController public class DemoController { @GetMapping("/hello") public String hel

Spring AOP定義註解實現許可權控制

1.建立註解類,controller控制層使用該註解進行許可權控制使用 import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.R

Spring Boot定義註解+AOP實現日誌記錄

訪問Controller列印的日誌效果如下:*********************************Request請求*************************************** ClassName : com.xxx.app.xxx.a

springboot aop 定義註解方式實現一套完善的日誌記錄(完整原始碼)

一:功能簡介 本文主要記錄如何使用aop切面的方式來實現日誌記錄功能。 主要記錄的資訊有: 操作人,方法名,引數,執行時間,操作型別(增刪改查),詳細描述,返回值。 二:專案結構圖 三:MAVEM依賴 本專案有兩個pom檔案,父類的pom檔案主要作用是對子類pom檔案依賴的版本號進行統一管理。 1.最外層

Spring】每個程式設計師都使用Spring(四)——Aop+定義註解日誌攔截

一、前言       上一篇部落格向大家介紹了Aop的概念,對切面=切點+通知 、連線點、織入、目標物件、代理(jdk動態代理和CGLIB代理)有所瞭解了。理論很強,實用就在這篇部落格介紹。       這篇部落格中,小編向大家介紹springAop很常見的

基於SSM利用SpringAOP切面及定義註解 記錄每次操作記錄(操作日誌 同理)

前段時間根據業務需求要記錄每次操作時的相關資訊:本帖方式通過在SpringMVC中的Controller設定一個自定義註解類來進行對資料的接收,通過 SpringAOP切面來對接收的資料進行邏輯處理. 在事先根據業務需求建立的一個實體類(如: UploadCount)的基礎

Spring boot 結合aop,定義註解,切面的理解

package com.imooc.boot.controller; import com.imooc.boot.aspect.IndexAspect; import org.springframework.web.bind.annotation.RequestMapping; import

aop+註解 記錄操作日誌

自定義註解: @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface OperateHis { int operateType() default 0; }

《SpringBoot學習篇》(5)AOP+定義註解實現日誌管理

用到的AOP註解:@Aspect  @Pointcut  @After 首先看一下如何呼叫自定義註解: @MyLog(module="老師模組", method="查詢全部") @RequestMapping("/all") public List

spring定義註解(annotation)與AOP中獲取註解

一、自定義註解(annotation) 自定義註解的作用:在反射中獲取註解,以取得註解修飾的類、方法或屬性的相關解釋。 package me.lichunlong.spring.annotation;

Spring+SpringMVC+Mybatis 利用AOP定義註解實現可配置日

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 5