Java 創建通用單例工具類(泛型)


1.情景展示

  我們在接觸單例設計模式的時候,只能創建簡單的單例,也就是哪個Java類需要控制成單例,就寫一個對應的工具類。例如:

  如上圖所示,就是單例的表現形式之一:餓漢式(也就是不管你需不需,我先創建一個對象再說,你要我就給,不要我也已經創建好了);

  創建單例,我們需要將構造方法私有化,這樣就可以保證調用該類時無法通過new來創建對象;

  另外,創建getInstance()方法,並需要被synchronized關鍵字修飾,以確保該對象同一時間只能被一個線程調用。

  那么,當我們有創建大量單例的需求時,總不能需要幾個就寫對應的類吧,這樣不僅降低代碼的可維護性,還會影響開發效率。

2.原因分析

  通過泛型來實現 

3.解決方案

import java.util.HashMap;
import java.util.Map;

/**
 * 單例模式+泛型
 * @description 所有的類都可以調用該類生成唯一的Java實例化對象
 * 調用者需要繼承該類,調用方法如下:
 * MySingleton s = (MySingleton) Singleton.getInstance(MySingleton.class);
 * @author: Marydon
 * @date: 2020年07月13日 0013 19:35
 */
public class SingletonUtils {
    //類初始化時,不初始化這個對象(延時加載,真正用的時候再創建)
    private static Map<Class<? extends SingletonUtils>, SingletonUtils> INSTANCES_MAP = new HashMap<>();

    /*
     * 無參構造方法
     * @attention: 這里不能再用private修飾了,因為該類是父類
     * @date: 2020年09月18日 0018 10:20
     */
    protected SingletonUtils() {
    }

    /*
     * 單例(懶漢式)
     * @date: 2020年07月13日 0013 19:50
     * @param: instanceClass
     * @return: com.xyh.bill.service.tools.Singleton
     */
    public synchronized static <E extends SingletonUtils> SingletonUtils getInstance(Class<E> instanceClass) throws Exception {
        if (INSTANCES_MAP.containsKey(instanceClass)) {
            return (E) INSTANCES_MAP.get(instanceClass);
        } else {
            E instance = instanceClass.newInstance();
            INSTANCES_MAP.put(instanceClass, instance);
            return instance;
        }
    }

}

  構造方法需要使用protect修飾,否則

4.調用

  確保要單例的Java對象,繼承上面的Java類; 

5.優化 

  這是一個接口請求的總入口,我們會發現通過泛型控制的單例模式,代碼還是冗余,因為我使用的是spring,由於IOC的特性,spring托管的bean對象都是唯一的,所以,我們完全可以通過注解來簡化代碼。

  首先,給需要單例的類添加注解(因為這里是服務層所以用的是@Service)

  在Controller層調用,需要注入該對象 

  這樣,我們就可以直接使用該對象啦

  這里需要注意的有兩點:   

  要想讓spring來管理java對象,需要在該類上添加@Component/@Service等注解;

  要想使用spring管理的bean對象,則調用該對象的類必須也是一個由spring來管理的對象,后者帶有Controller注解的控制器,否則,一個普通的類是無法獲取到spring管理的對象的,即使你加上@Autowired注解也沒用

  所以,能通過spring來管理的對象,盡量使用spring來完成。

 

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:

 


免責聲明!

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



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