SpringBoot通過Map實現天然的策略模式

😊 @ 作者: 一恍過去
💖 @ 主頁: https://blog.csdn.net/zhuocailing3390
🎊 @ 社區: Java技術棧交流
🎉 @ 主題: SpringBoot通過Map實現天然的策略模式
?? @ 創作時間: 2025年03月25日

目錄

  • 前言
  • 底層機制解析
    • Spring的集合類型自動裝配
    • @Resource注解的行為
    • 實現原理
  • 使用
    • 直接使用Map<String,T>
    • 指定Map中的bean類型
      • 定義策略接口
      • 定義實現類
      • 策略使用
      • 驗證
    • 自定義注解實現

前言

策略模式是一種行為設計模式,它允許在運行時選擇算法的行為。在Spring框架中,我們可以利用@Resource注解和Map集合來優雅地實現策略模式。

在Spring框架中,當你使用@Resource注解注入一個Map<String, T>時,Spring會自動將所有類型為T的bean收集到這個Map中,其中:

  • Key是bean的名稱
  • Value是bean實例

底層機制解析

Spring的集合類型自動裝配

Spring框架對集合類型的依賴注入有特殊處理:

  • 當注入List時,會收集所有類型為T的bean
  • 當注入Map<String, T>時,會收集所有類型為T的bean,并以bean名稱作為key

@Resource注解的行為

@Resource注解默認按名稱裝配,但當目標是一個Map時,Spring會特殊處理:

  • 如果Map的key是String類型,value是某個接口/類
  • Spring會查找所有實現該接口/繼承該類的bean
  • 將這些bean以"bean名稱->bean實例"的形式放入Map

實現原理

Spring在依賴注入時的處理流程:

  • 發現字段/方法參數是Map<String, T>類型
  • 在應用上下文中查找所有類型為T的bean
  • 創建一個新的Map實例
  • 遍歷找到的所有bean,以bean名稱作為key,bean實例作為value放入Map
  • 將這個Map注入到目標字段/參數中

使用

直接使用Map<String,T>

我們直接定義一個Controller,并且在Controller中使用@ResourceMap<String,T>

@RestController
@RequestMapping("/test")
public class TestController {@Resourceprivate Map<String, Object> beanMap = new ConcurrentHashMap<>();public void beanMap() {System.out.println(beanMap.size());}
}

驗證:
可以看到map中存了項目中所有的bean對象
在這里插入圖片描述

指定Map中的bean類型

在實際的開發中,我們希望Map中只是存儲需要的Bean,并且Controller中可以根據beanName進行轉發到不同的Service中,步驟如下:

定義策略接口

public interface PaymentStrategy {void pay();
}

定義實現類

	@Service("ALI")@Slf4jpublic class AliStrategyService implements PaymentStrategy {@Overridepublic void pay() {log.info("使用支付寶支付");}}@Service("WX")@Slf4jpublic class WxStrategyService implements PaymentStrategy {@Overridepublic void pay() {log.info("使用微信支付");}}

策略使用

@RestController
@RequestMapping("/test")
public class TestController {@Resourceprivate Map<String, PaymentStrategy> beanMap = new ConcurrentHashMap<>();public void beanMap() {PaymentStrategy wx = beanMap.get("WX");wx.pay();PaymentStrategy ali = beanMap.get("ALI");ali.pay();}
}

驗證

可以看到map中,就只有兩個Bean,并且key就是我們通過@Service(value)定義的名稱
在這里插入圖片描述
在這里插入圖片描述

自定義注解實現

  • 自定義一個注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface PaymentType {String value();
}
  • 注解替換:將原有的@Service(value)替換為@PaymentType (value),比如:
@PaymentType("CARD")
@Slf4j
public class CardStrategyService implements PaymentStrategy {@Overridepublic void pay() {log.info("使用銀行卡支付");}
}
  • **意義:**可以更好表示策略模式,讓其他開發人員一眼可以看出當前的Service使用了策略模式

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74569.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74569.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74569.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WordPress WooCommerce 本地文件包含漏洞(CVE-2025-1661)

免責聲明 僅供網絡安全研究與教育目的使用。任何人不得將本文提供的信息用于非法目的或未經授權的系統測試。作者不對任何由于使用本文信息而導致的直接或間接損害承擔責任。如涉及侵權,請及時與我們聯系,我們將盡快處理并刪除相關內容。 一:產品介紹 HUSKY – WooCommer…

matlab近似計算聯合密度分布

在 Matlab 中&#xff0c;當A和B是兩個序列數據時&#xff0c;可以通過以下步驟來近似求出A大于B的概率分布&#xff1a;數據準備&#xff1a;確保序列A和B具有相同的長度。如果長度不同&#xff0c;需要進行相應的處理&#xff08;例如截取或插值&#xff09;。計算A大于B的邏…

可視化動態表單動態表單界的天花板--Formily(阿里開源)

文章目錄 1、Formily表單介紹2、安裝依賴2.1、安裝內核庫2.2、 安裝 UI 橋接庫2.3、Formily 支持多種 UI 組件生態&#xff1a; 3、表單設計器3.1、核心理念3.2、安裝3.3、示例源碼 4、場景案例-登錄注冊4.1、Markup Schema 案例4.2、JSON Schema 案例4.3、純 JSX 案例 1、Form…

NAT 實驗:多私網環境下 NAPT、Easy IP 配置及 FTP 服務公網映射

NAT基本概念 定義&#xff1a;網絡地址轉換&#xff08;Network Address Translation&#xff0c;NAT&#xff09;是一種將私有&#xff08;保留&#xff09;地址轉化為合法公網 IP 地址的轉換技術&#xff0c;它被廣泛應用于各種類型 Internet 接入方式和各種類型的網絡中。作…

C語言-橋接模式詳解與實踐

文章目錄 C語言橋接模式詳解與實踐1. 什么是橋接模式&#xff1f;2. 為什么需要橋接模式&#xff1f;3. 實際應用場景4. 代碼實現4.1 UML 關系圖4.2 頭文件 (display_bridge.h)4.3 實現文件 (display_bridge.c)4.4 使用示例 (main.c) 5. 代碼分析5.1 關鍵設計點5.2 實現特點 6.…

el-table 合并單元格

vue2使用el-table合并單元格&#xff0c;包括合并行、合并列 <el-table:header-cell-style"handerMethod":span-method"arraySpanMethod"cell-click"handleCellClick":data"tableData"style"width: 100%"><el-tabl…

網絡安全之vlan實驗

在對vlan進行一定的學習之后我們來練習一個小實驗來加深理解記憶 首先是對實驗進行一個搭建 第一部分&#xff1a;給交換機配置vlan 首先是sw1 [Huawei]vlan batch 2 to 5 [Huawei]int g0/0/1 [Huawei-GigabitEthernet0/0/1]port hybrid tagged vlan 2 [Huawei-GigabitEthe…

STM32 - 在機器人、自動化領域,LL庫相比HAL優勢明顯

在機器人控制器、電機控制器等領域的開發&#xff0c;需要高實時性、精細化控制或者對代碼執行效率、占用空間有較高要求。所以&#xff0c;大家常用的HAL庫明顯不符合要求。再加上&#xff0c;我們學習一門技術&#xff0c;一定要學會掌握底層的原理。MCU開發的底層就是寄存器…

mysql中show命令的使用

在 MySQL 中&#xff0c;SHOW 命令是一個非常實用的工具&#xff0c;用于查詢數據庫元數據&#xff08;如數據庫、表、列、索引等信息&#xff09;。以下是常見的 SHOW 命令及其用法&#xff1a; 1. 顯示所有數據庫 SHOW DATABASES;列出服務器上的所有數據庫。 2. 顯示當前數據…

RAG優化:python從零實現query轉換增強技術

本篇仍然是不依賴于LangChain等專用庫,利用python基本庫實現了三種查詢轉換技術 查詢重寫:使查詢更加具體和詳細,以提高搜索精度。回退提示:生成更廣泛的查詢以檢索有用的上下文信息。子查詢分解:將復雜查詢分解為更簡單的組件,以實現全面檢索。圖 1:RAG 中的查詢重寫(…

登錄驗證碼的接口實習,uuid,code.

UID是唯一標識的字符串,下面是百度百科關于UUID的定義&#xff1a; UUID是由一組32位數的16進制數字所構成&#xff0c;是故UUID理論上的總數為16322128&#xff0c;約等于3.4 x 10^38。也就是說若每納秒產生1兆個UUID&#xff0c;要花100億年才會將所有UUID用完。 UUID的標準…

HTML5 初探:新特性與本地存儲的魔法

HTML5 初探&#xff1a;新特性與本地存儲的魔法 作為一名前端新手&#xff0c;你可能聽說過 HTML5 這個名詞。它是 HTML 的第五代版本&#xff0c;不僅讓網頁變得更強大&#xff0c;還帶來了許多新功能和工具。今天&#xff0c;我們就來聊聊 HTML5 的新特性&#xff0c;以及它…

雙指針---《移動零》

目錄 文章前言 題目描述 算法原理講解 忽略限制條件的解法 原理講解 思路總結 代碼展示 雙指針解法 原理講解 思路總結 代碼展示 大總結 &#x1f4ab;只有認知的突破&#x1f4ab;才來帶來真正的成長&#x1f4ab;編程技術的學習&#x1f4ab;沒有捷徑&#x1f4ab;…

jangow-01-1.0.1靶機攻略

1.進行配置&#xff0c;按住shift&#xff0c;在圖一界面按e進去得到圖二 .ro 替換為 rw signie init/bin/bash ctrlx&#xff0c;ip a查看網卡信息&#xff0c;修改配置文件網卡信息 修改為如圖所示內容后按shift?然后輸入wq點擊回車退出&#xff0c;然后重啟靶機 2.在kali中…

安全上網沙箱:多方面解決政企私的上網問題

在數字化的浪潮中&#xff0c;網絡已成為我們工作與生活不可或缺的一部分。然而&#xff0c;網絡的便捷也伴隨著諸多安全隱患&#xff0c;尤其是對于企業、個人以及政企機構而言&#xff0c;安全上外網成為了至關重要的課題。 隔離保護&#xff1a;構建安全堡壘 沙箱技術在內網…

C++ string的模擬實現

Hello!!大家早上中午晚上好&#xff0c;昨天復習了string的使用&#xff0c;今天來模擬實現一下string&#xff01;&#xff01;&#xff01; 一、string的框架搭建 1.1首先我們需要一個string的頭文件用來做變量、函數、類等聲明&#xff1b;再需要一個test文件來做測試,還需…

Java 中裝飾者模式與策略模式在埋點系統中的應用

前言 在軟件開發中&#xff0c;裝飾者模式和策略模式是兩種常用的設計模式&#xff0c;它們在特定的業務場景下能夠發揮巨大的作用。本文將通過一個實際的埋點系統案例&#xff0c;探討如何在 Java 中運用裝飾者模式和策略模式&#xff0c;以及如何結合工廠方法模式來優化代碼…

【3-22 list 詳解STL C++ 】

先看代碼&#xff0c;常用的就是代碼中有的那些 #include <bits/stdc.h> using namespace std; int main() {list<int> mylist;for(int i0;i<5;i){mylist.push_back(i);//TODO}for(const auto&i:mylist)cout<<i<<\n;//fanzhuanreverse(mylist.…

田間機器人幼苗視覺檢測與護苗施肥裝置研究(大綱)

田間機器人幼苗視覺檢測與護苗施肥裝置研究 基于多光譜視覺與精準施肥的農業機器人系統設計 第一章 緒論 1.1 研究背景與意義 農業智能化需求&#xff1a; 傳統幼苗檢測依賴人工&#xff0c;效率低且易遺漏弱苗/病苗施肥不精準導致資源浪費和環境污染 技術挑戰&#xff1a;…

如何在Linux CentOS上安裝和配置Redis

如何在Linux CentOS上安裝和配置Redis 大家好&#xff0c;我是曾續緣。歡迎來到本教程&#xff01;今天我將向您介紹在Linux CentOS上安裝和配置Redis的詳細步驟。Redis是一個高性能的鍵值存儲系統&#xff0c;常用于緩存、消息隊列和數據持久化等應用場景。讓我們一起開始吧&…