Java-SpringBoot-使用多型給專案解耦

Alickx 發表於 2022-06-12
Java Spring

Java-SpringBoot-使用多型給專案解耦

提及

今天在打算維護一下智慧社群這個專案的時候,想到專案是使用Satoken這個開箱即用的授權和認證的元件,因為在專案開啟的時候對SpringSecurity並不熟悉,而Satoken類似傻瓜式的,匯入依賴進去,配置一下獲取許可權和角色的方法即可使用。

但是由此帶來的問題就是,專案中充斥著Satoken的API方法,類似於StpUtil.isLogin(),StpUtil.getLoginIdAsLong()這類方法在Service層中已經是相當常見了,儘管是非常的方便,但是帶來的問題就是假如後面我要替換另外一款許可權認證和授權的元件,那麼這些API方法通通都需要進行修改,這種強耦合很明顯是不合理的。

我突然想到在SpringSecurity中,配置密碼加密方法的時候,我們可以選擇任意的密碼加密方法。

@Bean
public PasswordEncoder getPasswordEncoder() {
    return new BCryptPasswordEncoder();
}

那麼,我能不能也像這樣子,提供一個統一的介面,通過選擇實現方式的不同,從而達到當需要更換別的實現的時候,只需要更改該處程式碼即可

多型

其實這需要利用到Java的三大特性之一,多型。Java的三大特性分別是封裝,繼承和多型

這裡使用一個小例子來演示一下什麼是多型。

我們先建立一個介面,這個介面只需要含有我們統一所需的方法。

/**
 * @Author: Alickx
 * @Date: 2022/06/12/16:22
 * @Description: 統一介面
 */
public interface IRun {
    /**
     * 跑步
     */
    void run();
}

然後我們需要來建立幾個實現該介面的實現類

分別是Man.java和Woman.java

image-20220612163601702

/**
 * @Author: Alickx
 * @Date: 2022/06/12/16:27
 * @Description: 男人的實現類
 */
public class Man implements IRun{
    @Override
    public void run() {
        System.out.println("我是Man,我在run");
    }
}

image-20220612163632689

/**
 * @Author: Alickx
 * @Date: 2022/06/12/16:27
 * @Description: 女人的實現類
 */
public class Woman implements IRun{
    @Override
    public void run() {
        System.out.println("我是Woman,我在run");
    }
}

接著上面的提及,我們把Man和Woman想成是不同密碼加密方式,而run方法則是他們都需要實現的密碼加密方法

那我們試著來讓這幾個類例項化。

image-20220612163942217

/**
 * @Author: Alickx
 * @Date: 2022/06/12/9:13
 * @Description: main方法
 */
public class Demo8 {
    public static void main(String[] args) {
        // 使用man來例項化
        IRun human1 = new Man();
        human1.run();
        // 使用woman來例項化
        IRun human2 = new Woman();
        human2.run();
    }
}

這裡可以看出假如我們要將Man所實現的run要替換成Woman,我們並不需要修改很多程式碼,只需要將IRun human1 = new Man(); 替換成IRun human1 = new Woman(); 即可

實際專案改造

那使用多型這種特性,我們就可以建立一個統一的介面,業務程式碼都使用這個介面的方法,而通過實現該介面方法,從而可以選擇多種不同的實現方式。

那先建立一個AuthService介面,介面裡麵包含著我們業務程式碼所需要的api方法。

image-20220612164934235

然後建立AuthSatokenServiceImpl 實現類,該實現類是使用Satoken來實現介面裡面的方法。

image-20220612165110020

簡單呼叫一下Satoken的Api方法。

那麼介面有了,實現類有了,但是在Springboot專案中,我們將例項化交給了Spring來管理,所以還需要建立一個配置類,來讓Spring選擇需要例項化的類。

image-20220612165338727

Ok,那我們直接修改專案中的程式碼,這裡舉例一處。

原先的業務程式碼。

image-20220612165712589

想以上紅圈內的程式碼,我們需要獲取當前請求的使用者是否登入了,假如我們直接使用Satoken的API方法,那麼後面需要更換SpringSecurity或者其他一些元件的時候,就需要大面積的修改這些程式碼。

改造後:

先注入實現類

@Autowired
AuthService authService;

image-20220612165921410

這樣子就完成了解耦,假如需要更換其他的授權認證元件,只需要建立一個實現AuthService介面的實現類,然後修改一下配置類的例項即可

image-20220612170336397 image-20220612170428627

image-20220612170450706

更改該處即可,即可更換。