设计模式——spring自动注入+枚举类+策略模式


可以按照以下形式利用策略模式实现mysql/es搜索,qq/微信/gitee登录,上传本地/oss/minio等多种模式进行选择
原理和另外一篇文章基本一样设计模式——使用spring自动注入实现工厂模式
参考

定义策略接口


public interface SearchStrategy {
    /**
     * 搜索文章
     *
     * @param keywords 关键字
     * @return {@link List< ArticleSearchVO >} 文章列表
     */
    List<ArticleSearchVO> searchArticle(String keywords);
}

定义es/mysql两种搜索模式的业务类实现上面的接口

es:注意加上注解@Service(“elasticsearchStrategyImpl”)

@Service("elasticsearchStrategyImpl")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class EsSearchStrategyImpl implements SearchStrategy {

    @Override
    public List<ArticleSearchVO> searchArticle(String keywords) {
        System.out.println("使用elasticsearch搜索==========================》"+keywords);
        return null;
    }


}

mysql:注意加上注解@Service(“mysqlStrategyImpl”)

@Service("mysqlStrategyImpl")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MysqlSearchStrategyImpl implements SearchStrategy {


    @Override
    public List<ArticleSearchVO> searchArticle(String keywords){
        System.out.println("使用mysql搜索=================================》"+keywords);
        return null;
    }

}

定义一个枚举类

注意:枚举对象定义的搜索策略中的字符串"mysqlStrategyImpl"和"elasticsearchStrategyImpl"要与前面用@Service注入spring的bean名称一样

public enum SearchModelEnum {

    /**
     * mysql搜索
     */
    MYSQL(0, "mysql搜索", "mysqlStrategyImpl"),
    /**
     * elasticsearch搜索
     */
    ELASTICSEARCH(1, "elasticsearch搜索", "elasticsearchStrategyImpl");

    //创建构造函数
    SearchModelEnum(int code, String desc, String strategy) {
        this.type = code;
        this.desc = desc;
        this.strategy = strategy;
    }


    /**
     * 搜索方式
     */
    private final Integer type;
    /**
     * 描述
     */
    private final String desc;
    /**
     * 策略
     */
    private final String strategy;

    public Integer getType() {
        return type;
    }

    public String getDesc() {
        return desc;
    }

    public String getStrategy() {
        return strategy;
    }

    /**
     * 获取策略
     *
     * @param type 模式
     * @return {@link String} 搜索策略
     */
    public static String getStrategy(int type) {
        for (SearchModelEnum value : SearchModelEnum.values()) {
            if (value.getType() == (type)) {
                return value.getStrategy();
            }
        }
        return null;
    }



}

定义一个策略上下文(重点)

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SearchStrategyContext {
	//重点spring会自动注入map里的实现类,因此searchStrategyMap.get(searchMode)能获取到值
    private final Map<String, SearchStrategy> searchStrategyMap;

    /**
     * 执行搜索策略
     *
     * @param keywords 关键字
     * @return {@link List< ArticleSearchVO >} 搜索文章
     */
    public List<ArticleSearchVO> executeSearchStrategy(String searchMode, String keywords) {
        return searchStrategyMap.get(searchMode).searchArticle(keywords);
    }

}

调用1

这里searchModel=0,使用mysql搜索,业务searchModel的值应该从表中或者,这样可以动态修改搜索模式。

@RestController
@RequestMapping("search")
public class MyBatisPlusApplication {
    @Autowired
    private  SearchStrategyContext searchStrategyContext;
    @GetMapping
   public void serach(String keywords){
       //搜索模式【0:SQL搜索 、1:全文检索】  可建立一张配置表查询来获取searchModel
       int searchModel=0;
       String strategy = SearchModelEnum.getStrategy(searchModel);
       List<ArticleSearchVO> articleSearchVOS = searchStrategyContext.executeSearchStrategy(strategy, keywords);
   }

在这里插入图片描述

调用2

修改searchModel=1,使用es搜索
在这里插入图片描述

原理

核心在于SearchStrategyContext类当中定义的private final Map<String, SearchStrategy> searchStrategyMap;
可以看看到,我们并没有往该该map当中复制,可是依旧可以获取到里面对应的搜索实现类"elasticsearchStrategyImpl"和"mysqlStrategyImpl"调用其中的search方法。

原因如下Spring会自动将SearchStrategy接口的实现类注入到这个Map中(前提是实现类得是交给Spring 容器管理的),这个Map的key为bean id,可以用@Component(value = “xxx”)的方式设置,如果直接用默认的方式的话,就是首字母小写。value值则为对应的策略实现类)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值