자바 전략 모드의 테이블 디자인 및 코드 구현, if 분기를 완전히 해결하고 엔터프라이즈 수준 기능 활성화 및 비활성화 실현

하나, 설명

1. 전략 모드를 사용하는 이유는 무엇입니까?

  • 일부 비즈니스 시나리오에서 QQ 로그인, WeChat 로그인, Ali 계정 로그인 및 NetEase 계정을 사용한 타사 로그인을 추가하고 싶습니다. 그러나 어떤 이유로 인해 타사 로그인 중 하나가 더 이상 필요하지 않으며 환자가 타사를 제공하지 않습니다. 예를 들어 NetEase가 더 이상 로그인을 제공하지 않는 경우 코드를 수정하고 NetEase 계정 로그인 기능을 제거해야하지만 언젠가는 NetEase 회사 계정을 사용할 수 있으므로 수정해야합니다. 이 기능을 달성하기위한 코드

  • 전략 모드를 사용하면 백그라운드에 관리 목록이 있으며 특정 기능을 직접 비활성화 / 활성화 할 수 있습니다.
    여기에 사진 설명 삽입

  • 전략 ID (프런트 엔드 전송)를 통해 해당 컨테이너 벤드를 찾고 해당 구현 메서드를 호출합니다.

  • 타사가 더 이상 지원되지 않거나 원하지 않는 경우 비활성화하십시오. 다시 원할 경우 시작하십시오. 새 전략을 추가하려면 원래 코드를 모두 변경할 필요가 없습니다. 비즈니스 변화로 인한 일련의 숨겨진 문제를 피하기 위해 커플 링을 크게 줄입니다.

둘째, 코드 구현

현재 프로젝트는 springboot 2.0.1 + mybatis3.1을 사용합니다.

1. SQL 스크립트, 전략 테이블

CREATE TABLE `t_admin_strategy` (
  `id` varchar(32) NOT NULL COMMENT 'ID',
  `strategy_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '策略名',
  `strategy_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '策略id',
  `strategy_type` int(2) NOT NULL COMMENT '策略type(字典code)',
  `strategy_bean_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '策略执行 spring容器的beanid',
  `disable` int(1) NOT NULL DEFAULT '0' COMMENT '是否禁用(字典code 0-否 1-是)',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='策略';

2. 디렉토리 구조

메시지 전송 전략 및 결제 전략 추가

여기에 사진 설명 삽입

2. SpringUtils 도구 클래스

@Component
public class SpringUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}

3. AdminStrategy 전략 클래스

/**
 * 策略表
 */
@Data
@TableName("t_admin_strategy")
public class AdminStrategy {
    /**
     * 策略Id
     */
    private String id;
    /**
     * 策略名
     */
    private String strategyName;
    /**
     * 策略Id
     */
    private String strategyId;
    /**
     * 策略类型(如: 1-短信 2-支付 3-登录)
     */
    private Integer strategyType;
    /**
     * spring容器 beanId ,用于找到对应的策略方法
     */
    private String strategyBeanId;
    /**
     * 是否禁用
     */
    private Integer disable = 0;
}

3 、 AdminStrategyMapper

public interface AdminStrategyMapper  extends BaseMapper<AdminStrategy> {
}

4. StrategyContext 전략 ID가 벤드 클래스를 가져옵니다.

/**
 * 策略
 */
@Component
public class StrategyContext {

    @Autowired
    private AdminStrategyMapper strategyMapper;

    /**
     * 通过策略Id 寻找容器Id
     * @param strategyId
     * @param strategyType
     * @param t
     * @param <T>
     * @return
     */
    public <T> T getStrategy(String strategyId, Integer strategyType, Class<T> t) {
        // strategyId bean id 验证参数
        if (StringUtils.isEmpty(strategyId)) {
            return null;
        }
        if (strategyType == null) {
            return null;
        }
        if (t == null) {
            return null;
        }
        // 根据策略id查询 (策略id不能重复)
        AdminStrategy strategy = strategyMapper.selectOne(new LambdaQueryWrapper<AdminStrategy>()
                .eq(AdminStrategy::getStrategyId, strategyId)
                .eq(AdminStrategy::getStrategyType, strategyType)
                .eq(AdminStrategy::getDisable, 0)
        );
        if (strategy == null) {
            return null;
        }
        String strategyBeanId = strategy.getStrategyBeanId();
        if (StringUtils.isEmpty(strategyBeanId)) {
            return null;
        }
        T bean = SpringUtils.getBean(strategyBeanId, t);
        return bean;
    }
}

5. 지불 전략

상호 작용

/**
 * 支付策略
 */
public interface PayStrategy {

    String toHtml();
}

실현 1

/**
 * 策略if 阿里支付
 */
@Component
public class AliPayStrategy implements PayStrategy {
    @Override
    public String toHtml() {
        return "对接阿里";
    }
}

실현 2

/**
 * 策略if 银联支付
 */
@Component
public class UnionPayStrategy implements PayStrategy {
    @Override
    public String toHtml() {
        return "对接银联";
    }
}

6. 메시지 전송 전략

상호 작용

/**
 * 消息策略
 */
public interface MsgStrategy {
    /**
     * 共同行为方法
     *
     * @return
     */
    String sendMsg(String phone);
}

실현 1

/**
 * 策略if 阿里云发送短信
 */
@Component
public class AliYunStrategy implements MsgStrategy {
    @Override
    public String sendMsg(String phone) {
        return "使用阿里云发送短信";
    }
}

실현 2

/**
 * 策略if 华为发送短信
 */
@Component
public class HuaWeiStrategy implements MsgStrategy {
    @Override
    public String sendMsg(String phone) {
        return "使用华为发送短信";
    }
}

7. 테스트 인터페이스 클래스

@RestController
public class TestController{
    @Autowired
    private StrategyContext strategyContext;

    @GetMapping("/sendMsg")
    public String sendMsg(String strategyId, String phone) {
        // type = 短信
        MsgStrategy msgStrategy = strategyContext.getStrategy(strategyId, 1, MsgStrategy.class);
        if (msgStrategy == null) {
            return "当前渠道已经关闭或者是不存在";
        }
        return msgStrategy.sendMsg(phone);
    }


    @GetMapping("/toPayHtml")
    public String toPayHtml(String strategyId) {
        // type = 支付
        PayStrategy payStrategy = strategyContext.getStrategy(strategyId, 2, PayStrategy.class);
        if (payStrategy == null) {
            return "当前渠道已经关闭或者是不存在";
        }
        return payStrategy.toHtml();
    }
}

셋, 테스트

전략 테이블 데이터,
여기에 사진 설명 삽입

1. SMS 전략 테스트 보내기

다른 정책 ID를 전달하면 정책에 따라 다른 구현이 자동으로 호출됩니다.
여기에 사진 설명 삽입

여기에 사진 설명 삽입

2. 결제 전략 테스트

다른 정책 ID를 전달하면 정책에 따라 다른 구현이 자동으로 호출됩니다.
여기에 사진 설명 삽입
여기에 사진 설명 삽입

3. 채널 테스트를 닫습니다.

Alibaba Cloud SMS 기능 비활성화
여기에 사진 설명 삽입
가 종료되었습니다.
여기에 사진 설명 삽입

  • 위의 콘텐츠 중 일부는 Ant Classroom http://www.mayikt.com/ 에서 가져온 것입니다 .

  • 개인 오픈 소스 프로젝트 (유니버설 백그라운드 관리 시스템) –> https://gitee.com/wslxm/spring-boot-plus2 , 원하는 경우 확인할 수 있습니다.

  • 이 기사의 끝입니다. 유용하다고 생각되면 좋아요를 누르거나 관심을 가져 주시기 바랍니다. 계속해서 더 많은 콘텐츠를 업데이트 할 예정입니다. 시청 해 주셔서 감사합니다!

추천

출처blog.csdn.net/qq_41463655/article/details/108818881