SpringBoot如何通过Map实现策略模式

 更新时间:2025年03月27日 10:04:28   作者:一恍过去  
策略模式是一种行为设计模式,它允许在运行时选择算法的行为,在Spring框架中,我们可以利用@Resource注解和Map集合来优雅地实现策略模式,这篇文章主要介绍了SpringBoot如何通过Map实现策略模式,需要的朋友可以参考下

前言

策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在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 {
    @Resource
    private 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")
	@Slf4j
	public class AliStrategyService implements PaymentStrategy {
	    @Override
	    public void pay() {
	        log.info("使用支付宝支付");
	    }
	}
	@Service("WX")
	@Slf4j
	public class WxStrategyService implements PaymentStrategy {
	    @Override
	    public void pay() {
	        log.info("使用微信支付");
	    }
	}

策略使用

@RestController
@RequestMapping("/test")
public class TestController {
    @Resource
    private 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 {
    @Override
    public void pay() {
        log.info("使用银行卡支付");
    }
}

**意义:**可以更好表示策略模式,让其他开发人员一眼可以看出当前的Service使用了策略模式

到此这篇关于SpringBoot通过Map实现天然的策略模式的文章就介绍到这了,更多相关SpringBoot策略模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Data JPA实现动态条件与范围查询实例代码

    Spring Data JPA实现动态条件与范围查询实例代码

    本篇文章主要介绍了Spring Data JPA实现动态条件与范围查询实例代码,非常具有实用价值,需要的朋友可以参考下
    2017-06-06
  • springboot配合Thymeleaf完美实现遍历功能

    springboot配合Thymeleaf完美实现遍历功能

    Thymeleaf显然是一个开发页面的技术,现在各种前端技术层出不穷,比如现在主流的Vue、React、AngularJS等。这篇文章主要介绍了springboot配合Thymeleaf完美实现遍历,需要的朋友可以参考下
    2021-09-09
  • Java NIO异步文件通道原理及用法解析

    Java NIO异步文件通道原理及用法解析

    这篇文章主要介绍了Java NIO异步文件通道原理及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Java8中List转Map的多种方式代码

    Java8中List转Map的多种方式代码

    这篇文章主要给大家介绍了关于Java8中List转Map的多种方式,在实际项目中我们经常会用到List转Map操作,本文介绍了多种方法的实现代码,需要的朋友可以参考下
    2023-08-08
  • 实例详解SpringBoot默认的JSON解析方案

    实例详解SpringBoot默认的JSON解析方案

    JSON数据现在是我们开发中用的最多的,百分之九十的数据都是通过JSON方式进行传输,下面这篇文章主要给大家介绍了关于SpringBoot默认的JSON解析方案的相关资料,需要的朋友可以参考下
    2021-08-08
  • java Date获取本月的开始时间与结束时间

    java Date获取本月的开始时间与结束时间

    这篇文章主要为大家介绍了java Date获取本月的开始时间与结束时间示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2023-05-05
  • SpringBoot如何IDEA中实现热部署

    SpringBoot如何IDEA中实现热部署

    这篇文章主要介绍了SpringBoot如何IDEA中实现热部署,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • C语言指针数组案例详解

    C语言指针数组案例详解

    这篇文章主要介绍了C语言指针数组案例详解,本文通过案例详细的解释了指针与数组的初始化还有关系与应用,需要的朋友可以参考下这篇文章
    2021-07-07
  • 使用Springboot根据配置文件动态注入接口实现类

    使用Springboot根据配置文件动态注入接口实现类

    这篇文章主要介绍了使用Springboot根据配置文件动态注入接口实现类,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Mybatis执行update失败的解决

    Mybatis执行update失败的解决

    这篇文章主要介绍了Mybatis执行update失败的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论