欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot中使用AOP實現(xiàn)日志記錄功能

 更新時間:2024年05月19日 09:33:08   作者:哈__  
AOP的全稱是Aspect-Oriented Programming,即面向切面編程(也稱面向方面編程),它是面向對象編程(OOP)的一種補充,目前已成為一種比較成熟的編程方式,本文給大家介紹了SpringBoot中使用AOP實現(xiàn)日志記錄功能,需要的朋友可以參考下

AOP簡介

AOP的全稱是Aspect-Oriented Programming,即面向切面編程(也稱面向方面編程)。它是面向對象編程(OOP)的一種補充,目前已成為一種比較成熟的編程方式。

在傳統(tǒng)的業(yè)務處理代碼中,通常都會進行事務處理、日志記錄等操作。雖然使用OOP可以通過組合或者繼承的方式來達到代碼的重用,但如果要實現(xiàn)某個功能(如日志記錄),同樣的代碼仍然會分散到各個方法中。這樣,如果想要關閉某個功能,或者對其進行修改,就必須要修改所有的相關方法。這不但增加了開發(fā)人員的工作量,而且提高了代碼的出錯率。

為了解決這一問題,AOP思想隨之產生。AOP采取橫向抽取機制,將分散在各個方法中的重復代碼提取出來,然后在程序編譯或運行時,再將這些提取出來的代碼應用到需要執(zhí)行的地方。這種采用橫向抽取機制的方式,采用傳統(tǒng)的OOP思想顯然是無法辦到的,因為OOP只能實現(xiàn)父子關系的縱向的重用。雖然AOP是一種新的編程思想,但卻不是OOP的替代品,它只是OOP的延伸和補充。

創(chuàng)建日志數據庫 

創(chuàng)建日志記錄表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
 
-- ----------------------------
-- Table structure for sys_oper_log
-- ----------------------------
DROP TABLE IF EXISTS `sys_oper_log`;
CREATE TABLE `sys_oper_log`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主鍵',
  `operation` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '操作',
  `business_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '業(yè)務類型',
  `method` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '方法名稱',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '操作時間',
  `oper_name` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作用戶',
  `params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '參數',
  `ip` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '請求的ip地址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2058 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '操作日志記錄' ROW_FORMAT = Dynamic;
 
SET FOREIGN_KEY_CHECKS = 1;

創(chuàng)建用戶表 

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
 
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
  `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名 ',
  `age` int(11) NULL DEFAULT NULL COMMENT '年齡 ',
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '郵箱 ',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
 
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (2, 'Jack', 20, 'test2@baomidou.com');
INSERT INTO `user` VALUES (3, 'Tom', 28, 'test3@baomidou.com');
INSERT INTO `user` VALUES (4, 'Sandy', 21, 'test4@baomidou.com');
INSERT INTO `user` VALUES (5, 'Billie', 24, 'test5@baomidou.com');
INSERT INTO `user` VALUES (6, 'sss', 18, '123@qq.com');
INSERT INTO `user` VALUES (8, 'sss', 18, '123@qq.com');
 
SET FOREIGN_KEY_CHECKS = 1;

簡單看一下表格的結構,我這里的數據就不給大家展示了。

SpringBoot使用AOP

一、導入依賴

下邊的三個依賴是我們的核心依賴。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
         <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

二、創(chuàng)建我們的項目結構

  • 創(chuàng)建UserMapper
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
  • 創(chuàng)建UserService
public interface UserService extends IService<User> {
}
  • 創(chuàng)建UserServiceImpl
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
  • 創(chuàng)建UserController
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Log(operation = "查找用戶",businessType = BusinessType.LIST)
    @RequestMapping("/find-user")
    public String findUser(){
        return userService.list().toString();
    }
}

創(chuàng)建兩個實體

  • 創(chuàng)建User
@Data
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    
}
  • 創(chuàng)建SysOperLog
@Data
@TableName("sys_oper_log")
public class SysOperLog {
 
        @TableId(type = IdType.AUTO)
        private Long id;
 
        private String operation;
 
        private String businessType;
 
        private String method;
 
        @TableField(fill = FieldFill.INSERT)
        private LocalDateTime createTime;
 
        private String operName;
 
        private String params;
 
        private String ip;
}

三、使用AOP

1.創(chuàng)建枚舉類

這個枚舉類的作用就是記錄我們調用的接口是什么樣的一個類型的,是查找、刪除還是其他。

public enum BusinessType {
    /**
     * 其它
     */
    OTHER,
 
    /**
     * 新增
     */
    INSERT,
 
    /**
     * 修改
     */
    UPDATE,
 
    /**
     * 刪除
     */
    DELETE,
    
    /**
     * 瀏覽
     */
    LIST
}

2..創(chuàng)建Log注解

默認的操作為空,默認的操作類型是OTHER。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
    /**
     * 操作名稱
     * @return
     */
    String operation() default "";
 
    /**
     * 操作的類型
     * @return
     */
    BusinessType businessType() default BusinessType.OTHER;
}

3.創(chuàng)建切面類

@Aspect
@Component
public class LogAspect {
    @Pointcut("@annotation(com.qcby.annotation.Log)")
    public void pointCut(){}
 
    @Autowired
    HttpServletRequest request;
    @Autowired
    SysOperLogMapper sysOperLogMapper;
 
    @After(value = "pointCut()")
    public void afterLogWrite(JoinPoint joinPoint){
        // 創(chuàng)建日志對象
        SysOperLog sysOperLog = new SysOperLog();
        // 獲取我們調用的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
 
        // 獲取方法上的Log注解,因為我們要獲取注解中的一些信息
        Log log = method.getAnnotation(Log.class);
 
        // 獲取我們調用的類的名稱
        String className = joinPoint.getTarget().getClass().getName();
        // 獲取調用的方法的名稱
        String methodName = method.getName();
        // 重新修改一下我們調用的方法 是全路徑的
        methodName = className + methodName;
 
        // 獲取方法的參數
        Object[] args = joinPoint.getArgs();
        ObjectMapper objectMapper = new ObjectMapper();
        String params = "";
        try {
            params =  objectMapper.writeValueAsString(args);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
 
        // 獲取注解中的操作名稱
        String operation = log.operation();
        // 獲取注解中的操作類型
        String businessType = log.businessType().toString();
 
        // 這里的操作人員僅靠后端是寫不了的  需要前端的token認證  我直接把操作人員改為admin
        String username = "admin";
 
        // 獲取ip地址
        String ipAddress = IpUtil.getIpAddr(request);
 
        sysOperLog.setBusinessType(businessType);
        sysOperLog.setOperation(operation);
        sysOperLog.setMethod(methodName);
        sysOperLog.setParams(params);
        sysOperLog.setIp(ipAddress);
        sysOperLog.setOperName(username);
        sysOperLog.setCreateTime(LocalDateTime.now());
        
        sysOperLogMapper.insert(sysOperLog);
        
    }
}

4.IpUtil

public class IpUtil {
    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST = "127.0.0.1";
    private static final String SEPARATOR = ",";
 
    public static String getIpAddr(HttpServletRequest request) {
        System.out.println(request);
        String ipAddress;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (LOCALHOST.equals(ipAddress)) {
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 對于通過多個代理的情況,第一個IP為客戶端真實IP,多個IP按照','分割
            // "***.***.***.***".length()
            if (ipAddress != null && ipAddress.length() > 15) {
                if (ipAddress.indexOf(SEPARATOR) > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        return ipAddress;
    }
}

5.進行測試

我們在瀏覽器上輸入網址:

127.0.0.1:8080/user/find-user

數據是沒問題的,接下來我們只需要查看數據的日志文件是否插入了日志就好了。 

這里我查找了兩次,一次使用的localhost,另一次使用的127.0.0.1。日志可以成功記錄。 

以上就是SpringBoot中使用AOP實現(xiàn)日志記錄功能的詳細內容,更多關于SpringBoot AOP日志記錄的資料請關注腳本之家其它相關文章!

相關文章

  • Java?循環(huán)隊列/環(huán)形隊列的實現(xiàn)流程

    Java?循環(huán)隊列/環(huán)形隊列的實現(xiàn)流程

    循環(huán)隊列又叫環(huán)形隊列,是一種特殊的隊列。循環(huán)隊列解決了隊列出隊時需要將所有數據前移一位的問題。本文將帶大家詳細了解循環(huán)隊列如何實現(xiàn),需要的朋友可以參考一下
    2022-02-02
  • IDEA設置Tab選項卡快速的操作

    IDEA設置Tab選項卡快速的操作

    這篇文章主要介紹了IDEA設置Tab選項卡快速的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 淺談Timer和TimerTask與線程的關系

    淺談Timer和TimerTask與線程的關系

    下面小編就為大家?guī)硪黄獪\談Timer和TimerTask與線程的關系。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • spring mvc 實現(xiàn)獲取后端傳遞的值操作示例

    spring mvc 實現(xiàn)獲取后端傳遞的值操作示例

    這篇文章主要介紹了spring mvc 實現(xiàn)獲取后端傳遞的值操作,結合實例形式詳細分析了spring mvc使用JSTL 方法獲取后端傳遞的值相關操作技巧
    2019-11-11
  • java的http請求工具對比分析

    java的http請求工具對比分析

    本文對比了Java中五種流行的HTTP客戶端庫:HttpURLConnection、ApacheHttpClient、OkHttp、Feign和SpringRestTemplate,涵蓋了它們的特性、優(yōu)勢、劣勢以及適用場景,感興趣的朋友一起看看吧
    2025-03-03
  • Struts 2 配置Action詳解

    Struts 2 配置Action詳解

    本篇文章主要介紹了Struts 2 配置Action詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 解決SpringBoot ClassPathResource的大坑(FileNotFoundException)

    解決SpringBoot ClassPathResource的大坑(FileNotFoundException)

    這篇文章主要介紹了解決SpringBoot ClassPathResource的大坑(FileNotFoundException),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 使用springboot制作博客管理系統(tǒng)

    使用springboot制作博客管理系統(tǒng)

    這篇文章主要介紹了使用springboot制作博客管理系統(tǒng),文中有非常詳細的代碼示例,對正在學習springboot的小伙伴有很大的幫助,感興趣的小伙伴可以參考一下
    2021-08-08
  • mybatis?返回Map類型key默認為大寫問題

    mybatis?返回Map類型key默認為大寫問題

    這篇文章主要介紹了mybatis?返回Map類型key默認為大寫問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java硬幣翻轉倍數遞增試算實例

    Java硬幣翻轉倍數遞增試算實例

    這篇文章主要介紹了Java硬幣翻轉倍數遞增試算實例,有需要的朋友可以參考一下
    2013-12-12

最新評論