SpringAOP01 利用AOP實現權限驗證、利用權限驗證服務實現權限驗證


1 編程范式

  1.1 面向過程

  1.2 面向對象

  1.3 面向切面編程

  1.4 函數式編程

  1.5 事件驅動編程

 

2 什么是面向切面編程

  2.1 是一種編程范式,而不是一種編程語言

  2.2 解決一些特定的問題

  2.3 作為面向對象編程的一種補充

 

3  AOP產生的初衷

  3.1 解決代碼重復性問題 Don't Repeat Yourself

  3.2 解決關注點分離問題 Separation of Concerns

    3.2.1 水平分離(技術上划分)

      控制層 -> 服務層 -> 持久層

    3.2.2 垂直分離(模塊上划分)

      模塊划分

    3.2.3 切面分離(功能上划分)

      分離功能性需求和非功能性需求

 

4 使用AOP的好處

  4.1 集中處理某一個關注點、橫切邏輯

  4.2 可以很方便地添加、刪除關注點

  4.3 侵入性減少,增強代碼可讀性和可維護性

  

5 AOP的使用場景

  5.1 權限控制

  5.2 緩存控制

  5.3 事物控制

  5.4 審計日志

  5.5 性能監控

  5.6 分布式追蹤

  5.7 異常處理

  

6 利用傳統方法實現權限驗證

  6.1 創建一個springBoot項目

    下載地址:點擊前往

  6.2 新建一個Product實體類

  Product.java

  6.3 新建一個權限模擬類

    該類主要用來設定用戶和獲取用戶

復制代碼
package cn.test.demo.base_demo.security;

/**
 * @author 王楊帥
 * @create 2018-04-29 17:15
 * @desc 模擬用戶登錄,該類可以設定用戶和獲取用戶
 **/
public class CurrentSetHolder {
    private final static ThreadLocal<String> holder = new ThreadLocal<>();

    /**
     * 獲取用戶
     * @return
     */
    public static String get() {
        return holder.get() == null ? "unknown" : holder.get();
    }

    /**
     * 設定用戶
     * @param user
     */
    public static void set(String user) {
        holder.set(user);
    }
}
復制代碼

  6.4 新建一個權限校驗類

    該類主要用於判斷當前用戶是否是“admin”用戶

復制代碼
package cn.test.demo.base_demo.service;

import cn.test.demo.base_demo.security.CurrentSetHolder;
import org.springframework.stereotype.Component;

/**
 * @author 王楊帥
 * @create 2018-04-29 17:19
 * @desc 權限校驗服務類
 **/
@Component
public class AuthService {

    /**
     * 權限檢查,如果用戶不是 “admin" 就會報錯
     */
    public void checkAccess() {
        String user = CurrentSetHolder.get();
        if (!"admin".equals(user)) {
            throw new RuntimeException("operation not allow.");
        }
    }
}
復制代碼

  6.5 新建ProductService類

    該類主要實現對Product的一些操作

  ProductService.java

  6.6 創建一個服務層測試類

    在調用ProductService的insert方法前對用戶進行設定

  ProductServiceTest.java

 

7 利用AOP實現權限驗證

  7.1 新建一個springBoot項目

    下載地址:點擊前往

  7.2 創建一個Product實體類

復制代碼
package cn.test.demo.base_demo.entity;

/**
 * @author 王楊帥
 * @create 2018-04-29 17:11
 * @desc 商品實體類
 **/
public class Product {
    private Integer id;
    private String name;

    public Product() {
    }

    public Product(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
復制代碼

  7.3 創建一個AdminOnly注解

復制代碼
package cn.test.demo.base_demo.security;

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)
public @interface AdminOnly {
}
復制代碼

  7.4 新建一個權限模擬類

    該類主要用來設置用戶和獲取用戶

復制代碼
package cn.test.demo.base_demo.security;

/**
 * @author 王楊帥
 * @create 2018-04-29 17:15
 * @desc 模擬用戶登錄,該類可以設定用戶和獲取用戶
 **/
public class CurrentSetHolder {
    private final static ThreadLocal<String> holder = new ThreadLocal<>();

    /**
     * 獲取用戶
     * @return
     */
    public static String get() {
        return holder.get() == null ? "unknown" : holder.get();
    }

    /**
     * 設定用戶
     * @param user
     */
    public static void set(String user) {
        holder.set(user);
    }
}
復制代碼

  7.5 創建一個切面類

    該類主要對所有使用了@AdminOnly注解的方法進行權限校驗

復制代碼
package cn.test.demo.base_demo.security;

import cn.test.demo.base_demo.service.AuthService;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author 王楊帥
 * @create 2018-04-29 17:37
 * @desc 權限檢查的AOP類
 **/
@Aspect
@Component
public class SecurityAspect {
    @Autowired
    AuthService authService;

    @Pointcut("@annotation(AdminOnly)")
    public void adminOnly(){

    }

    @Before("adminOnly()")
    public void check(){
        authService.checkAccess();
    }
}
復制代碼

  7.6 新建一個ProductService服務類

    該類的delete方法用了@AdminOnly注解,所以delete方法會進行權限校驗

  ProductService.java

  7.7 創建一個測試類

    productService.delete(id) 方法中有權限驗證,如果不是“admin"用戶就會報錯【利用AOP實現的】

  ProductServiceTest.java

  7.8 源代碼

    點擊前往


免責聲明!

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



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