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

SpringBoot整合Aop全過程

 更新時間:2024年10月17日 17:06:23   作者:小疙瘩的編程之路  
AOP(面向切面編程)技術可以高效地解決日志記錄、事務管理、權限控制等問題,日志記錄通過自定義注解和切面類,自動記錄方法調用詳情,減少重復代碼,事務管理方面,通過AOP可以在不改變業(yè)務代碼的情況下,實現事務的自動開啟、提交和回滾,保證數據一致性

AOP 可以做什么?

  • 1. 日志記錄
  • 自動記錄方法的調用、參數、返回值和異常等信息,減少了在每個方法中添加日志代碼的需要。
  • 2. 管理事務
  • 在方法執(zhí)行前后自動處理事務的開啟、提交和回滾,確保數據的一致性和完整性。
  • 3. 權限控制
  • 實現方法的訪問控制,檢查用戶權限,確保只有授權用戶才能執(zhí)行特定操作。
  • 4. 性能監(jiān)控
  • 自動收集方法的執(zhí)行時間、調用次數等性能指標,幫助開發(fā)者進行性能分析和優(yōu)化。
  • 5. 緩存管理
  • 實現方法結果的緩存,減少重復計算,提高系統(tǒng)性能。
  • 6. 異常處理
  • 統(tǒng)一處理方法執(zhí)行中的異常,簡化異常捕獲和處理邏輯。
  • 7. 輸入驗證
  • 在方法執(zhí)行前對輸入參數進行驗證,保證數據的有效性和完整性。
  • 8. 動態(tài)代理
  • 創(chuàng)建代理對象,在不修改原有類的情況下添加額外的行為。

應用場景

  • Web開發(fā):用于請求處理、事務管理、安全控制等。
  • 企業(yè)應用:在服務層實現統(tǒng)一的日志和異常處理。
  • 微服務:在服務之間進行統(tǒng)一的監(jiān)控和熔斷處理。

日志記錄

1.準備工作

首先需要導入AOP依賴

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.50</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

然后需要創(chuàng)建日志記錄數據庫和實體類還有在Mapper層實現插入數據方法

  • 實體類
//操作日志實體類
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperateLog {
    private Integer id; //主鍵ID
    private Integer operateUser; //操作人ID
    private LocalDateTime operateTime; //操作時間
    private String className; //操作類名
    private String methodName; //操作方法名
    private String methodParams; //操作方法參數
    private String returnValue; //操作方法返回值
    private Long costTime; //操作耗時
}
  • Mapper接口
@Mapper
public interface OperateLogMapper {

    //插入日志數據
    @Insert("insert into operate_log (operate_user, operate_time, class_name, method_name, method_params, return_value, cost_time) " +
            "values (#{operateUser}, #{operateTime}, #{className}, #{methodName}, #{methodParams}, #{returnValue}, #{costTime});")
    public void insert(OperateLog log);

}

2.創(chuàng)建自定義注解和切面類

因為我們要記錄的操作日志是對于數據的增,刪,改所以采用@annotation來指定要為連接點的方法。

而且在涉及到消耗時間的字段,所以需要采用@Around通知類型

  • 自定義注解類
@Retention(RetentionPolicy.RUNTIME)//運行時有效
@Target(ElementType.METHOD)//作用在方法上
public @interface Log {
}

3.實現日志記錄(Around)

首先需要需要記錄的操作接口方法前加上@Log注解

接下來在切面類中實現操作日志記錄:

@Aspect
@Component
public class LogAsper {
    @Autowired
    private OperateLogMapper operateLogMapper;
    @Autowired
    private HttpServletRequest request;

    @Around("@annotation(com.ly.springbootdemotlias.anno.Log)")//匹配加了Log注解的方法
    public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {
        OperateLog operateLog = new OperateLog();
        //獲取操作人id,通過獲取并解析jwt令牌
        String jwt = request.getHeader("token");
        Claims claims = JwtUtils.parseJwt((jwt));
        Integer operateUser =(Integer) claims.get("id");
        operateLog.setOperateUser(operateUser);
        //獲取操作時間
        operateLog.setOperateTime(LocalDateTime.now());
        //獲取操作類名
        operateLog.setClassName(joinPoint.getTarget().getClass().getName());
        //獲取操作方法名
        operateLog.setMethodName(joinPoint.getSignature().getName());
        //獲取操作方法參數
        operateLog.setMethodParams(Arrays.toString(joinPoint.getArgs()));
        //獲取開始時間
        long begin = System.currentTimeMillis();
        //獲取操作方法返回值
        Object result = joinPoint.proceed();
        String returnValue = JSONObject.toJSONString(result);
        operateLog.setReturnValue(returnValue.toString());
        //獲取操作結束時間
        long end = System.currentTimeMillis();
        //獲取操作耗時
        operateLog.setCostTime((end-begin));
        operateLogMapper.insert(operateLog);
        return  result;

    }
}

管理事務

1. 添加依賴

在 pom.xml 中添加 MyBatis-Plus 和 AOP 的依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.0</version> <!-- 根據需要選擇版本 -->
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

2. 配置 MyBatis-Plus

在 application.yml 中配置 MyBatis-Plus 和數據源:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/your_database
    username: your_username
    password: your_password
    driver-class-name: com.mysql.cj.jdbc.Driver
  mybatis-plus:
    mapper-locations: classpath*:/mappers/**/*.xml

3. 創(chuàng)建事務切面

創(chuàng)建一個事務切面類:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Aspect
@Component
public class TransactionAspect {

    @Transactional
    @Around("execution(* com.yourpackage.service..*(..))") // 指定需要事務的業(yè)務邏輯包
    public Object manageTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result;
        try {
            result = joinPoint.proceed(); // 執(zhí)行目標方法
            return result;
        } catch (Exception e) {
            throw e; // 拋出異常以觸發(fā)回滾
        }
    }
}

4. 示例業(yè)務邏輯類

創(chuàng)建一個服務類,使用 MyBatis-Plus 進行數據庫操作:

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

@Service
public class UserService extends ServiceImpl<UserMapper, User> {

    public void createUser(User user) {
        this.save(user); // 調用 MyBatis-Plus 的 save 方法
    }
}

5. 用戶實體和 Mapper

  • 定義用戶實體:
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

@TableName("users") // 數據庫表名
public class User {
    @TableId
    private Long id;
    private String name;

    // getters and setters
}
  • Mapper 接口:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface UserMapper extends BaseMapper<User> {
    // 可以自定義額外的方法
}

6. 創(chuàng)建控制器

在控制器中調用 UserService 的 createUser 方法:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public String createUser(@RequestBody User user) {
        userService.createUser(user); // 調用 UserService 的 createUser 方法
        return "User created successfully"; // 返回成功消息
    }
}

7. 啟動類

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

心得

  • 通過以上步驟,你可以在 Spring Boot 項目中整合 AOP 和 MyBatis-Plus,實現簡單而有效的事務管理。
  • 這樣,無論是在正常情況下提交事務,還是在出現異常時回滾事務,都能得到很好的支持。

為什么做事務,做事務有啥用

  • 事務確保一組操作要么全部成功,要么全部失敗,從而保持數據的一致性和完整性。
  • 它們在處理銀行轉賬、訂單處理等場景時尤其重要,可以防止數據不一致、部分更新或系統(tǒng)故障導致的數據丟失。
  • 通過事務,確保即使在異常情況下,數據狀態(tài)依然可靠。

那為什么要結合aop去做事務

  • 結合 AOP(面向切面編程)可以將事務管理的邏輯與業(yè)務邏輯分離,提高代碼的可維護性和可讀性。
  • 通過 AOP,可以在不修改業(yè)務代碼的情況下,集中管理事務,簡化代碼結構,并實現事務的自動化管理,減少重復代碼,提高開發(fā)效率。

權限控制

1. 添加依賴

在 pom.xml 中添加 AOP 相關依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 創(chuàng)建權限注解

定義一個自定義注解 @RequiresPermission:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermission {
    String value();
}

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

創(chuàng)建切面類,使用 @Aspect 注解來定義切面,處理權限控制邏輯:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class PermissionAspect {

    @Autowired
    private UserService userService; // 獲取用戶服務

    @Around("@annotation(requiresPermission)") // 攔截使用 @RequiresPermission 注解的方法
    public Object checkPermission(ProceedingJoinPoint joinPoint, RequiresPermission requiresPermission) throws Throwable {
        String requiredPermission = requiresPermission.value(); // 獲取所需權限

        // 權限檢查邏輯
        if (!hasPermission(requiredPermission)) {
            throw new SecurityException("Permission denied: " + requiredPermission);
        }

        return joinPoint.proceed(); // 執(zhí)行目標方法
    }

    private boolean hasPermission(String permission) {
        User currentUser = userService.getCurrentUser(); // 獲取當前用戶

        if (currentUser == null) {
            return false; // 用戶未登錄
        }

        return currentUser.getPermissions().contains(permission); // 檢查權限
    }
}

在使用 AOP 時,@RequiresPermission 注解是一個標記,它本身并不直接傳遞參數。Spring AOP 在攔截帶有該注解的方法時,會自動創(chuàng)建該注解的實例,并將其作為參數傳遞給

checkPermission 方法。這是通過 AOP 框架的代理機制實現的,而不是通過顯式調用。具體來說,當被注解的方法被調用時,AOP 會攔截這個調用并注入相應的注解信息。

permission 參數來源于 @RequiresPermission 注解的 value() 方法。在 checkPermission 方法中,當該方法攔截到一個使用 @RequiresPermission 注解的方法時,Spring AOP 會將該注解的實例作為第二個參數傳遞給 checkPermission 方法。因此,你可以通過調用 requiresPermission.value() 來獲取注解中定義的權限字符串。

4. 使用權限注解

在需要進行權限控制的方法上使用自定義注解

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/admin")
    @RequiresPermission("ADMIN_ACCESS")
    public String adminAccess() {
        return "Welcome, admin!";
    }
}

5. 配置 Spring Boot

確保 Spring Boot 應用程序能夠掃描到切面和自定義注解。通常情況下,只需在主類中添加 @EnableAspectJAutoProxy 注解:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

@EnableAspectJAutoProxy 注解的作用是啟用 Spring 的 AOP(面向切面編程)支持,允許使用 AspectJ 的代理機制來實現切面。具體來說,它有以下幾個功能:

1.啟用代理

它告訴 Spring 創(chuàng)建代理對象,這些代理對象可以攔截方法調用并執(zhí)行切面邏輯。

2.支持注解

當你在代碼中使用注解(如 @Around、@Before 等)時,@EnableAspectJAutoProxy 會使這些注解生效,從而實現方法攔截和切面邏輯的執(zhí)行。

3.簡化配置

通過添加這個注解,開發(fā)者不需要額外的 XML 配置,只需通過注解來定義切面和增強,減少了配置的復雜性。

在主類中添加這個注解后,Spring Boot 應用會自動掃描到切面類并將其注冊到應用上下文中,從而實現所需的 AOP 功能。

AOP的五種通知類型包括‌

  • 前置通知(@Before)‌
  • 后置通知(@After)‌
  • 返回通知(@AfterReturning)‌
  • 異常通知(@AfterThrowing)‌
  • 環(huán)繞通知(@Around)‌

每種通知類型都有其特定的用途和場景,可以根據實際需求選擇使用。

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • springboot?+rabbitmq+redis實現秒殺示例

    springboot?+rabbitmq+redis實現秒殺示例

    本文主要介紹了springboot?+rabbitmq+redis實現秒殺示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • Java實現異步延遲隊列的方法詳解

    Java實現異步延遲隊列的方法詳解

    目前系統(tǒng)中有很多需要用到延時處理的功能,本文就為大家介紹了Java實現異步延遲隊列的方法,文中的示例代碼講解詳細,需要的可以參考一下
    2023-03-03
  • java中反射和注解的簡單使用方法

    java中反射和注解的簡單使用方法

    相信大家對注解和反射應該并不陌生,在現在信息飛速發(fā)展的年代,各種優(yōu)秀的框架或許都離不開注解的使用,這篇文章主要給大家介紹了關于java中反射和注解的簡單使用方法,需要的朋友可以參考下
    2021-08-08
  • 淺談java監(jiān)聽器的作用

    淺談java監(jiān)聽器的作用

    這篇文章主要介紹了淺談java監(jiān)聽器的作用,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Intellij IDEA 添加jar包的三種方式(小結)

    Intellij IDEA 添加jar包的三種方式(小結)

    這篇文章主要介紹了Intellij IDEA 添加jar包的三種方式(小結),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 詳解spring batch的使用和定時器Quart的使用

    詳解spring batch的使用和定時器Quart的使用

    spring Batch是一個基于Spring的企業(yè)級批處理框架,它通過配合定時器Quartz來輕易實現大批量的數據讀取或插入,并且全程自動化,無需人員管理
    2017-08-08
  • java mybatis框架實現多表關系查詢功能

    java mybatis框架實現多表關系查詢功能

    這篇文章主要介紹了java mybatis框架實現多表關系查詢,基于Maven框架的整體設計 —— 一多一的關系,文中通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • mybatis-plus查詢源碼詳解

    mybatis-plus查詢源碼詳解

    這篇文章主要介紹了mybatis-plus查詢源碼解讀,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • java 獲取當前函數名的實現代碼

    java 獲取當前函數名的實現代碼

    以下是對使用java獲取當前函數名的實現代碼進行了介紹。需要的朋友可以過來參考下
    2013-08-08
  • SpringCloud如何使用Eureka實現服務之間的傳遞數據

    SpringCloud如何使用Eureka實現服務之間的傳遞數據

    這篇文章主要介紹了SpringCloud使用Eureka實現服務之間的傳遞數據操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論