springboot中的策略模式

场景介绍:

底层agent扫描云主机中安装的各类中间件,以OS为维度全量上报。

服务层需要拆分入库,并且判断是否已注册。例如:kafka、redis、was、tomcat、pgsql、Hadoop、linux、windows等等吧。

我们可以用一堆if..else 进行各种判断,也可以用传统的策略模式,new一个一个对象,分别处理。

但是这都不是优雅的编程方式,更不满足开闭原则。

做一个3秒程序员,上面那些方式不是我们要做的。

例如,业务下次扫描范围增加了,k8s,clickhouse、elasticsearch等,就要修改原始代码。

Springboot采用的是注册机制,启动会生成一个一个bean,使用时只需要注入即可。

所有传统的策略模式需要升级为Springboot+策略模式,核心就是自定义注解和@Autowired.

  • context
  • 行为接口
  • 自定义注解 - -用于生成和寻找对应bean
  • 具体bean

1、自定义注解

用来标志各种资源bean,一一对应。

/**
 * desc
 *
 * @Author 红尘过客
 * @DateTime 2023-08-02 16:05:23
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface SourceType {
    /**
     * 资源类型
     * 
     * @return
     */
    String type();
}

2、行为接口

接口由来标志对应能力

可以对json对象,vo对象等进行处理。

/**
 * 资源上报处理策略
 *
 * @Author 红尘过客
 * @DateTime 2023-08-02 16:09:21
 */
public interface ISourceHandleStrategy {
    void handle(JSONObject sourceJson);
}

3、策略上下文

package com.wht.test.strategy;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 上报资源处理策略上下文
 * 本质是容器中收录所有处理器
 *
 * @Author 红尘过客
 * @DateTime 2023-08-02 16:12:56
 */
@Service
public class SourceHandleContext {
    private Map<String, ISourceHandleStrategy> sourceHandleStrategyMap;

    /**
     * 上下文装载所有处理器
     * 
     * @param list
     */
    @Autowired
    public void setSourceHandleStrategyMap(List<ISourceHandleStrategy> list) {
        sourceHandleStrategyMap = list.stream().collect(Collectors.toMap(
                sourceHandleStrategy -> AnnotationUtils.findAnnotation(sourceHandleStrategy.getClass(),
                        SourceType.class).type(), sourceHandleStrategy -> sourceHandleStrategy,
                (value1, value2) -> value1));
    }

    public void handle(JSONObject jsonObject) {
        String type = jsonObject.getString("source_type"); // 加入go-agent扫描上来的对象,用source_type标注类型
        if (sourceHandleStrategyMap != null && sourceHandleStrategyMap.size() > 0) {
            ISourceHandleStrategy sourceHandleStrategy = sourceHandleStrategyMap.get(type);
            if (sourceHandleStrategy != null) {
                // 如果对应中间件有对应的处理器,就进行上报等处理
                sourceHandleStrategy.handle(jsonObject);
            }
        }
    }
}

4、增加两个处理器

was处理器

/**
 * desc
 *
 * @Author 红尘过客
 * @DateTime 2023-08-02 16:24:22
 */
@SourceType(type = "was")
@Slf4j
public class WasHandler implements ISourceHandleStrategy{
    @Override
    public void handle(JSONObject sourceJson) {
        log.info("was 处理器处理逻辑");
    }
}

oracle处理器

@SourceType(type = "oracle")
@Slf4j
public class OracleHandler implements ISourceHandleStrategy{
    @Override
    public void handle(JSONObject sourceJson) {
        log.info("oracle 处理器处理逻辑");
    }
}

5、使用示例

只需拿到上下文,把要处理的数据扔进去,就可以按照对应的策略,自动找到对应的bean进行处理。

@Slf4j
@Component
public class TestClient {
    @Autowired
    private SourceHandleContext sourceHandleContext;

    @Scheduled(cron = "* * * * * * ")
    public void bizHandler(){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("source_type","was");
        sourceHandleContext.handle(jsonObject);
    }
}

看下运行结果:

2023-08-02 16:35:54.006  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:35:55.003  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:35:56.012  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:35:57.003  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:35:58.008  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:35:59.011  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:36:00.007  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:36:01.007  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:36:02.016  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
2023-08-02 16:36:03.013  INFO 12172 --- [   scheduling-1] com.wht.test.strategy.WasHandler         : was 处理器处理逻辑
posted @ 2023-08-02 16:31  红尘过客2022  阅读(132)  评论(0编辑  收藏  举报