最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot頂層接口實(shí)現(xiàn)類注入項(xiàng)目的方法示例

 更新時(shí)間:2024年06月17日 08:55:11   作者:木星mx  
本文主要介紹了SpringBoot頂層接口實(shí)現(xiàn)類注入項(xiàng)目的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1、背景

在項(xiàng)目中,我們通常會(huì)具有同一特性的業(yè)務(wù)類定義一個(gè)頂層接口,讓業(yè)務(wù)類實(shí)現(xiàn)這個(gè)接口,通過接口規(guī)范來管理這些類。我們將這些實(shí)現(xiàn)接口的業(yè)務(wù)類交托給Spring容器接口后,有時(shí)候需要根據(jù)業(yè)務(wù)類型來選擇動(dòng)態(tài)選擇對(duì)應(yīng)的業(yè)務(wù)類阿里處理業(yè)務(wù)。這個(gè)時(shí)候就獲取到這些業(yè)務(wù)類并進(jìn)行管理,在需要時(shí)取出對(duì)應(yīng)的業(yè)務(wù)類處理業(yè)務(wù)。如何管理就是本期要介紹的內(nèi)容。

以下是我定義的一個(gè)簡(jiǎn)單的頂層接口,它有兩個(gè)方法,一個(gè)是提供類型的getType()方法,一個(gè)是處理業(yè)務(wù)的hanlde()方法。我們的任務(wù)就是對(duì)其實(shí)現(xiàn)類進(jìn)行管理,當(dāng)需要時(shí)可根據(jù)類型獲取對(duì)應(yīng)實(shí)現(xiàn)類。

public interface IBaseHandler {
    /**
     * 獲取處理器類型
     * @return 處理器類型
     */
    int getType();

    /**
     * 處理業(yè)務(wù)
     * @param t 業(yè)務(wù)數(shù)據(jù)
     * @param <T> 業(yè)務(wù)數(shù)據(jù)類型
     */
    <T> void handler(T t);
}

2、簡(jiǎn)單的管理方法

我們可以通過使用@Autowired注解將所有實(shí)現(xiàn)了IBaseHandler接口的類注入到項(xiàng)目當(dāng)中,并在需要時(shí)遍歷業(yè)務(wù)類對(duì)象,獲取對(duì)應(yīng)的對(duì)象來處理業(yè)務(wù)。代碼如下所示:

    @Autowired
    private List<IBaseHandler> handlers;
     /**
     * 處理業(yè)務(wù)
     * @param type 業(yè)務(wù)類型
     * @param data 業(yè)務(wù)數(shù)據(jù)
     * @param <T> 業(yè)務(wù)數(shù)據(jù)類型
     */
    public <T> void handle(int type, T data) {
        handlers.stream().filter(handler -> handler.getType() == type).findAny().orElseThrow(() -> {
            // 獲取不到業(yè)務(wù)類對(duì)象時(shí)打印日志并拋出異常
            log.error("Failed to get handler, type:{}", type);
            throw new NoSuchElementException("No such handler");
        }).handler(data);
    }

3、更好的管理方法

1、簡(jiǎn)單管理方法的弊端

上面的簡(jiǎn)單管理方法用起來方便,但是有兩個(gè)弊端:
(1)耦合度高,所有需要使用該接口的地方都需要進(jìn)行注入再遍歷的過程。
(2)性能較差,每次執(zhí)行業(yè)務(wù)之前都需要遍歷一次列表。

2、解決

我們可以使用一個(gè)工具類,提供靜態(tài)方法來獲取業(yè)務(wù)類。這樣所有需要獲取業(yè)務(wù)類的地方,就都可以通過該工具類一步獲取到所需的業(yè)務(wù)類。代碼如下:

1、工具類代碼

@Slf4j
public class HandlerManager {
    /**
     * 按照type映射的處理器map
     */
    private static Map<Integer, IBaseHandler> typeHandlerMap = new HashMap<>();
    /**
     * 按照類型映射的處理器map
     */
    private static Map<Class<IBaseHandler>, IBaseHandler> clazzHandlerMap = new HashMap<>();

    /**
     * 初始化方法,項(xiàng)目啟動(dòng)時(shí)調(diào)用該方法來初始化map
     * @param applicationContext spring 上下文對(duì)象
     */
    public static void init(ApplicationContext applicationContext) {
        List<IBaseHandler> handlers = new ArrayList<>();
        applicationContext.getBeansOfType(IBaseHandler.class).forEach((name, obj) -> handlers.add(obj));
        // 為了方便,兩次循環(huán)構(gòu)建map,一次循環(huán)也可以解決,不過人為定義的handler數(shù)量不多,一次循環(huán)性能提升不大
        typeHandlerMap = handlers.stream().collect(Collectors.toMap(IBaseHandler::getType, obj -> obj));
        clazzHandlerMap = handlers.stream().collect(Collectors.toMap(obj -> (Class<IBaseHandler>) obj.getClass(), obj -> obj));
    }

    public IBaseHandler getHandlerByType(int type) {
        return Optional.ofNullable(typeHandlerMap.get(type)).orElseThrow(() -> {
            // 獲取不到處理器打印日志并拋出異常
            log.info("Failed to get handler, type:{}", type);
            throw new NoSuchElementException("No such  handler error");
        });
    }

    public IBaseHandler getHandlerByClass(Class<IBaseHandler> clazz) {
        return Optional.ofNullable(clazzHandlerMap.get(clazz)).orElseThrow(() -> {
            // 獲取不到處理器打印日志并拋出異常
            log.info("Failed to get handler, clazz:{}", clazz);
            throw new NoSuchElementException("No such  handler error");
        });
    }


}

2、調(diào)用工具類的init方法

由于工具類提供的是靜態(tài)方法,因此無法通過注入的方式來獲取到所有的IBaseHanlder,所以需要借助其他可注入IBaseHanlder的類來初始化管理對(duì)象,以下是方法:

/**
 * 項(xiàng)目初始化類
 * 繼承ApplicationContextAware,實(shí)現(xiàn)setApplicationContext,可獲取ApplicationContext來獲取上下文
 */
@Component
public class ApplicationInit implements ApplicationContextAware {

    @Autowired
    private List<IBaseHandler> handlers;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 調(diào)用處理器工具類初始化方法
        HandlerManager.init(applicationContext);
    }
}

到此這篇關(guān)于SpringBoot頂層接口實(shí)現(xiàn)類注入項(xiàng)目的方法示例的文章就介紹到這了,更多相關(guān)SpringBoot類注入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • java基礎(chǔ)--自己動(dòng)手實(shí)現(xiàn)一個(gè)LRU

    java基礎(chǔ)--自己動(dòng)手實(shí)現(xiàn)一個(gè)LRU

    這篇文章主要介紹了運(yùn)用方案如何實(shí)現(xiàn)LUR,文章中通過代碼講解的非常詳細(xì),對(duì)大家的工作或?qū)W習(xí)有一定的參考價(jià)值,感興趣的朋友可以參考一下
    2021-08-08
  • Java中的Caffeine加載與驅(qū)逐策略詳解

    Java中的Caffeine加載與驅(qū)逐策略詳解

    這篇文章主要介紹了Java中的Caffeine加載與驅(qū)逐策略詳解,Caffeine是基于Java 8的高性能緩存庫,可提供接近最佳的命中率,Caffeine與ConcurrentMap相應(yīng),但是不完全相同,本文主要介紹Caffeine,需要的朋友可以參考下
    2023-10-10
  • Mybatis Interceptor 攔截器的實(shí)現(xiàn)

    Mybatis Interceptor 攔截器的實(shí)現(xiàn)

    這篇文章主要介紹了Mybatis Interceptor 攔截器的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • SpringBoot整合Web之AOP配置詳解

    SpringBoot整合Web之AOP配置詳解

    面向切面編程(aspect-oriented programming,AOP)主要實(shí)現(xiàn)的目的是針對(duì)業(yè)務(wù)處理過程中的切面進(jìn)行提取,諸如日志、事務(wù)管理和安全這樣的系統(tǒng)服務(wù),從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率
    2022-08-08
  • java實(shí)現(xiàn)隨機(jī)數(shù)生成器

    java實(shí)現(xiàn)隨機(jī)數(shù)生成器

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)隨機(jī)數(shù)生成器,隨機(jī)數(shù)生成小程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 解析Java的Hibernate框架中的持久化類和映射文件

    解析Java的Hibernate框架中的持久化類和映射文件

    這篇文章主要介紹了Java的Hibernate框架中的持久化類和映射文件,Hibernate是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-12-12
  • springboot中如何使用@Async方法

    springboot中如何使用@Async方法

    這篇文章主要介紹了springboot中如何使用@Async方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 使用maven打包生成doc文檔和打包源碼

    使用maven打包生成doc文檔和打包源碼

    這篇文章主要介紹了使用maven打包生成doc文檔和打包源碼的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java設(shè)計(jì)模式七大原則之里氏替換原則詳解

    Java設(shè)計(jì)模式七大原則之里氏替換原則詳解

    在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,里氏替換原則(Liskov Substitution principle)是對(duì)子類型的特別定義。本文將為大家詳細(xì)介紹Java設(shè)計(jì)模式七大原則之一的里氏替換原則,需要的可以參考一下
    2022-02-02
  • Spring事務(wù)失效的9大場(chǎng)景與解決方法

    Spring事務(wù)失效的9大場(chǎng)景與解決方法

    在日常開發(fā)中,我們經(jīng)常使用Spring事務(wù),這篇文章主要來和大家聊聊Spring事務(wù)失效的 9 種場(chǎng)景,并提供了相應(yīng)的解決方法,有需要的小伙伴可以參考一下
    2025-04-04

最新評(píng)論

大同县| 临安市| 辽宁省| 中卫市| 普安县| 离岛区| 喀喇| 枣庄市| 龙陵县| 图木舒克市| 长宁区| 连云港市| 朝阳县| 平阳县| 房产| 城市| 清镇市| 咸阳市| 云龙县| 青州市| 龙岩市| 青阳县| 明水县| 阿拉善右旗| 宁河县| 金乡县| 德化县| 克什克腾旗| 湖州市| 霍州市| 昌宁县| 库伦旗| 黄石市| 镇赉县| 罗城| 朝阳市| 石渠县| 五莲县| 江源县| 道孚县| 鄂伦春自治旗|