1つ、説明
1.なぜ戦略モードを使用するのですか?
-
一部のビジネスシナリオでは、QQログイン、WeChatログイン、Aliアカウントログイン、およびNetEaseアカウントを使用したサードパーティログインを追加したいのですが、何らかの理由で、サードパーティログインのいずれかが不要になり、サードパーティは患者から提供されていません。たとえば、NetEaseがログインを提供しなくなったため、コードを変更し、NetEaseアカウントのログイン機能を削除する必要がありますが、いつかNetEaseの企業アカウントを使用できるようになるため、変更する必要があります。この機能を実現するためのコード
-
ストラテジーモードを使用すると、バックグラウンドで管理リストが作成され、特定の機能を直接無効/有効にできます。
-
ストラテジーID(フロントエンド転送)から対応するコンテナベンドを見つけ、対応する実装メソッドを呼び出します
-
サードパーティがサポートされなくなった場合、または不要な場合は、無効にします。再度必要な場合は、開始します。新しい戦略を追加する場合は、元のコードをすべて変更する必要はありません。これにより、カップリングが大幅に削減され、ビジネスの変化によって引き起こされる一連の隠れた問題が回避されます。
第二に、コードの実装
現在のプロジェクトはspringboot2.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();
}
}
3、テスト
戦略テーブルデータ、
1.SMS戦略テストを送信します
異なるポリシーIDを渡すと、ポリシーに従って異なる実装が自動的に呼び出されます
2.支払い戦略テスト
異なるポリシーIDを渡すと、ポリシーに従って異なる実装が自動的に呼び出されます
3.チャネルテストを閉じます
AlibabaCloudのSMS機能を無効にする機能
が終了しました
-
上記のコンテンツの一部は、Ant Classroomhttp ://www.mayikt.com/からのものです。
-
パーソナルオープンソースプロジェクト(ユニバーサルバックグラウンド管理システム)–> https://gitee.com/wslxm/spring-boot-plus2、必要に応じてチェックアウトできます
-
これでこの記事は終わりです。お役に立てば幸いです。気に入ったり、注目したりしてください。今後もコンテンツを更新していきます...ご覧いただきありがとうございます。