精讲23种设计模式-策略模式~聚合短信服务和聚合支付服务

文章目录

          • 一、设计模式
            • 1. 为什么需要使用设计模式
            • 2. 设计模式的分类
            • 3. 什么是策略模式
            • 4. 为什么叫做策略模式
            • 5. 策略模式优缺点
            • 6. 策略模式应用场景
            • 7. Spring框架中使用的策略模式
          • 二、策略模式~聚合短信服务
            • 2.1. 依赖引入
            • 2.2. 抽象公共行为接口
            • 2.3. 具体策略接口实现类
            • 2.4. 策略枚举
            • 2.5. 获取具体策略实现
            • 2.6. 策略工厂
            • 2.7. 聚合短信服务测试
          • 三、聚合短信服务2
            • 3.1. 策略工厂调整
            • 3.2. 聚合短信测试
          • 四、聚合短信3
            • 4.1. 策略上下文
            • 4.2. SpringContext上下文工具类
            • 4.3. 聚合短信测试
          • 五、聚合短信+聚合支付(企业内部升级)
            • 5.1. 相关SQL语句
            • 5.2. 策略实体
            • 5.3. 策略接口
            • 5.4.策略上下文
            • 5.5. 聚合短信和聚合支付测试
            • 5.6. mapper扫描配置
            • 5.7. 依赖
            • 5.8. yml配置
            • 5.9. 开源地址

一、设计模式
1. 为什么需要使用设计模式

使用设计模式可以重构整体架构代码、提交代码复用性、扩展性、减少代码冗余问题。

2. 设计模式的分类

创建型模式
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为模式
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

策略模式

3. 什么是策略模式

策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,最终可以实现解决多重if判断问题。

1.环境(Context)角色:持有一个Strategy的引用。
2.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
3.具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

定义策略接口->实现不同的策略类->利用多态或其他方式调用策略

4. 为什么叫做策略模式

每个if判断都可以理解为就是一个策略。

5. 策略模式优缺点

优点
算法可以自由切换(高层屏蔽算法,角色自由切换)
避免使用多重条件判断(如果算法过多就会出现很多种相同的判断,很难维护)
扩展性好(可自由添加取消算法 而不影响整个功能)
缺点
策略类数量增多(每一个策略类复用性很小,如果需要增加算法,就只能新增类)
所有的策略类都需要对外暴露(使用的人必须了解使用策略,这个就需要其它模式来补充,比如工厂模式、代理模式)

6. 策略模式应用场景

聚合支付平台
比如搭建聚合支付平台的时候,这时候需要对接很多第三方支付接口,比如支付宝、微信支付、小米支付等。
通过传统if代码判断的,后期的维护性非常差!
这时候可以通过策略模式解决多重if判断问题。

7. Spring框架中使用的策略模式

ClassPathXmlApplicationContext Spring底层Resource接口采用策略模式

Spring 为 Resource 接口提供了如下实现类:
UrlResource:访问网络资源的实现类。
ClassPathResource:访问类加载路径里资源的实现类。
FileSystemResource:访问文件系统里资源的实现类。
ServletContextResource:访问相对于 ServletContext 路径里的资源的实现类:
InputStreamResource:访问输入流资源的实现类。
ByteArrayResource:访问字节数组资源的实现类。
1、new ClassPathXmlApplicationContext("");
2.进入该构造函数
在这里插入图片描述
在这里插入图片描述
4.SpringBean初始化 SimpleInstantiationStrategy

SimpleInstantiationStrategy 简单初始化策略
CglibSubclassingInstantiationStrategy CGLIB初始化策略

二、策略模式~聚合短信服务

在这里插入图片描述

2.1. 依赖引入
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.gblfy</groupId><artifactId>design-pattern</artifactId><version>0.0.1-SNAPSHOT</version><name>design-pattern</name><description>design-pattern</description><properties><java.version>1.8</java.version></properties><dependencies><!--字符串工具类--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><!--数据json处理--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.79</version></dependency><!--SpringMVC--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
2.2. 抽象公共行为接口

MsgStrategy

package com.gblfy.strategy;/*** 抽象公共行为接口** @author gblfy* @date 2022-03-13*/
public interface MsgStrategy {/*** 共同行为方法** @param phone* @return*/String sendMsg(String phone);
}
2.3. 具体策略接口实现类

调用(阿里云)短信息服务

package com.gblfy.strategy.impl;import com.gblfy.strategy.MsgStrategy;
import org.springframework.stereotype.Service;/*** 调用(阿里云)短信息服务** @author gblfy* @date 2022-03-13*/
@Service
public class AliYunStrategy implements MsgStrategy {@Overridepublic String sendMsg(String phone) {return "调用(阿里云)短信息服务";}
}

调用(华为云)短信息服务

package com.gblfy.strategy.impl;import com.gblfy.strategy.MsgStrategy;
import org.springframework.stereotype.Service;/*** 调用(华为云)短信息服务** @author gblfy* @date 2022-03-13*/
@Service
public class HuaWeiStrategy implements MsgStrategy {@Overridepublic String sendMsg(String phone) {return "调用(华为云)短信息服务";}
}

调用(腾讯云)短信息服务

package com.gblfy.strategy.impl;import com.gblfy.strategy.MsgStrategy;
import org.springframework.stereotype.Service;/*** 调用(腾讯云)短信息服务** @author gblfy* @date 2022-03-13*/
@Service
public class TencentStrategy implements MsgStrategy {@Overridepublic String sendMsg(String phone) {return "调用(腾讯云)短信息服务";}
}
2.4. 策略枚举
package com.gblfy.enums;/*** 策略枚举,存放所有策略的实现** @author gblfy* @date 2022-03-13*/
public enum SmsEnumStrategy {/*** 支付宝短信*/ALI_SMS("com.gblfy.strategy.impl.AliYunStrategy"),/*** 华为云短信*/HUAWEI_SMS("com.gblfy.strategy.impl.HuaWeiStrategy"),/*** 腾讯云短信*/TENCENT_SMS("com.gblfy.strategy.impl.TencentStrategy");/*** class 名称*/private String className;SmsEnumStrategy(String className) {this.setClassName(className);}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}
}
2.5. 获取具体策略实现
package com.gblfy.strategy;import com.gblfy.factory.StrategyFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;/*** 获取具体策略实现** @author gblfy* @date 2022-03-13*/
@Component
public class SmsContextStrategy {/*** 获取具体策略实现*/public String getStrategy(String strategyId, String phone) {if (StringUtils.isEmpty(strategyId)) {return "paycode 不能为空";}//    第1种:使用策略工厂获取具体策略的实现MsgStrategy msgStrategy = StrategyFactory.getPayStrategy(strategyId);if (msgStrategy == null) {return ",没有找到具体策略的实现...";}return msgStrategy.sendMsg(phone);}
}
2.6. 策略工厂
package com.gblfy.factory;import com.gblfy.enums.SmsEnumStrategy;
import com.gblfy.strategy.MsgStrategy;/*** 使用策略工厂获取具体策略实现** @author gblfy* @date 2022-03-13*/
public class StrategyFactory {//工厂初始化public static MsgStrategy getPayStrategy(String strategyType) {try {// 1.获取枚举中classNameString className = SmsEnumStrategy.valueOf(strategyType).getClassName();// 2.使用java反射技术初始化类return (MsgStrategy) Class.forName(className).newInstance();} catch (Exception e) {return null;}}
}
2.7. 聚合短信服务测试
/*** 测试链接:*     http://localhost:8080/sendMsgByEnumSfactory?strategyId=ALI_SMS&phone=123456*     http://localhost:8080/sendMsgByEnumSfactory?strategyId=HUAWEI_SMS&phone=123456*     http://localhost:8080/sendMsgByEnumSfactory?strategyId=TENCENT_SMS&phone=123456*/
package com.gblfy.controller;import com.gblfy.strategy.SmsContextStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MsgController {@Autowiredprivate SmsContextStrategy contextStrategy;/*** 使用枚举+工厂+策略模式实现聚合短信服务* * @param strategyId 策略ID* @param phone  手机号码* @return*/@GetMapping("/sendMsgByEnumSfactory")public String sendMsgByEnumSfactory(@RequestParam("strategyId") String strategyId,@RequestParam("phone") String phone) {return contextStrategy.getStrategy(strategyId, phone);}/*** 测试链接:*     http://localhost:8080/sendMsgByEnumSfactory?strategyId=ALI_SMS&phone=123456*     http://localhost:8080/sendMsgByEnumSfactory?strategyId=HUAWEI_SMS&phone=123456*     http://localhost:8080/sendMsgByEnumSfactory?strategyId=TENCENT_SMS&phone=123456*/
}

在这里插入图片描述

三、聚合短信服务2

1.使用工厂模式初始化具体策略class
2.将所有具体实现的策略存放到map集合中(枚举类中)
3.key:ALI_PAY value:com.gblfy.service.AliPayStrategy

3.1. 策略工厂调整
package com.gblfy.factory;import com.gblfy.strategy.MsgStrategy;
import com.gblfy.strategy.impl.AliYunStrategy;
import com.gblfy.strategy.impl.HuaWeiStrategy;
import com.gblfy.strategy.impl.TencentStrategy;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;public class FactoryStrategy {private static Map<String, MsgStrategy> msgStrategyMap = new ConcurrentHashMap<>();static {msgStrategyMap.put("huawei", new HuaWeiStrategy());msgStrategyMap.put("tencent", new TencentStrategy());msgStrategyMap.put("aliyun", new AliYunStrategy());}public static MsgStrategy getContextStrategy(String strategyId) {return msgStrategyMap.get(strategyId);}
}
3.2. 聚合短信测试
package com.gblfy.controller;import com.gblfy.factory.FactoryStrategy;
import com.gblfy.strategy.MsgStrategy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MsgController {/*** 使用工厂+策略模式实现聚合短信服务** @param strategyId* @param phone* @return*/@GetMapping("/sendMsgByfactory")public String sendMsgByfactory(@RequestParam("strategyId") String strategyId,@RequestParam("phone") String phone) {MsgStrategy contextStrategy = FactoryStrategy.getContextStrategy(strategyId);return contextStrategy.sendMsg(phone);}/*** 测试链接:*     http://localhost:8080/sendMsgByfactory?strategyId=huawei&phone=123456*     http://localhost:8080/sendMsgByfactory?strategyId=tencent&phone=123456*     http://localhost:8080/sendMsgByfactory?strategyId=aliyun&phone=123456*/
}
四、聚合短信3

使用springIOC代替反射,提高效率,动态切换(无需改动项目)

4.1. 策略上下文
package com.gblfy.strategy;import com.gblfy.utils.SpringContextUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;@Component
public class StrategyContext {public MsgStrategy getStrategy(String strategyId) {if (StringUtils.isEmpty(strategyId)) {return null;}return SpringContextUtils.getBean(strategyId, MsgStrategy.class);}}
4.2. SpringContext上下文工具类
package com.gblfy.utils;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;/*** 获取Spring上下文工具类** @author gblfy* @date 2022-03-13*/
@Component
public class SpringContextUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringContextUtils.applicationContext = applicationContext;}//获取applicationContextpublic 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返回指定的Beanpublic static <T> T getBean(String name, Class<T> clazz) {return getApplicationContext().getBean(name, clazz);}}
4.3. 聚合短信测试
   /*** 使用工厂+策略模式+SpringIOC实现聚合短信服务** @param strategyId* @param phone* @return*/@GetMapping("/sendMsgBySpringIOC")public String sendMsgBySpringIOC(@RequestParam("strategyId") String strategyId,@RequestParam("phone") String phone) {MsgStrategy contextStrategy = strategyContext.getStrategy(strategyId);return contextStrategy.sendMsg(phone);}/*** 测试链接:*     http://localhost:8080/sendMsgBySpringIOC?strategyId=aliYunStrategy&phone=123456*     http://localhost:8080/sendMsgBySpringIOC?strategyId=huaWeiStrategy&phone=123456*     http://localhost:8080/sendMsgBySpringIOC?strategyId=tencentStrategy&phone=123456*/
五、聚合短信+聚合支付(企业内部升级)
5.1. 相关SQL语句
drop database  IF EXISTS `design_pattern`;
create database `design_pattern`;
use `design_pattern`;SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for gblfy_strategy
-- ----------------------------
DROP TABLE IF EXISTS `gblfy_strategy`;
CREATE TABLE `gblfy_strategy`  (`id` int NOT NULL AUTO_INCREMENT 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 NOT NULL COMMENT '策略类型(0-支付服务,1-短信服务)',`strategy_bean_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '策略执行beanid实例',`deleted` int NOT NULL COMMENT '逻辑删除字段(0-有效 1-无效,默认为0)',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '策略配置表' ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of gblfy_strategy
-- ----------------------------
INSERT INTO `gblfy_strategy` VALUES (6, '腾讯云短信', 'tencent_sms', 1, 'tencentStrategy', 0);
INSERT INTO `gblfy_strategy` VALUES (7, '阿里云短信', 'aliYun_sms', 1, 'aliYunStrategy', 0);
INSERT INTO `gblfy_strategy` VALUES (8, '华为云短信', 'huaWei_sms', 1, 'huaWeiStrategy', 0);
INSERT INTO `gblfy_strategy` VALUES (9, '阿里支付', 'ali_pay', 0, 'aliPayStrategy', 0);
INSERT INTO `gblfy_strategy` VALUES (10, '银联支付', 'yinlian_pay', 0, 'unionPayStrategy', 0);SET FOREIGN_KEY_CHECKS = 1;
5.2. 策略实体
package com.gblfy.entity;import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;@Data
@TableName("gblfy_strategy")
public class GblfyStrategy {// 策略配置主键@TableId(value = "id", type = IdType.ASSIGN_ID)private Long id;//策略名称(阿里云短信、银联支付)@TableField("strategy_name")private String strategyName;//策略ID@TableField("strategy_id")private String strategyId;//策略类型(发短信或者调用支付)@TableField("strategy_type")private String strategyType;//策略具体执行beanId@TableField("strategy_bean_id")private String strategyBeanId;//逻辑删除字段@TableLogicprivate Integer deleted;
}
5.3. 策略接口
package com.gblfy.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gblfy.entity.GblfyStrategy;/*** 策略接口** @author gblfy* @date 2022-03-13*/
public interface StragegyMapper extends BaseMapper<GblfyStrategy> {
}
5.4.策略上下文
package com.gblfy.strategy;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gblfy.entity.GblfyStrategy;
import com.gblfy.mapper.StragegyMapper;
import com.gblfy.utils.SpringContextUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class StrategyContext {@Autowiredprivate StragegyMapper stragegyMapper;// public MsgStrategy getStrategy(String strategyId) {//     if (StringUtils.isEmpty(strategyId)) {//         return null;//     }//     return SpringContextUtils.getBean(strategyId, MsgStrategy.class);// }// public <T> T getStrategy(String stragegyId,Class<T> t){//     if (StringUtils.isEmpty(stragegyId)){//         return null;//     }//     return SpringContextUtils.getBean(stragegyId, t);// }public <T> T getStrategy(String stragegyId, String stragegyType, Class<T> t) {if (StringUtils.isEmpty(stragegyId)) {return null;}if (StringUtils.isEmpty(stragegyType)) {return null;}if (t == null) {return null;}//根据策略id和策略类型查询具体策略实例beanIdGblfyStrategy gblfyStrategy = stragegyMapper.selectOne(new QueryWrapper<GblfyStrategy>().lambda().eq(GblfyStrategy::getStrategyId, stragegyId).eq(GblfyStrategy::getStrategyType, stragegyType));if (gblfyStrategy == null) {return null;}String strategyBeanId = gblfyStrategy.getStrategyBeanId();if (StringUtils.isEmpty(strategyBeanId)) {return null;}return SpringContextUtils.getBean(strategyBeanId, t);}
}
5.5. 聚合短信和聚合支付测试
/*** 多个不同服务(短信+支付)抽象封装* mysql+SpringIOC+策略模式实现聚合短信服务和聚合支付服务** @param strategyId* @param stragegyType* @param phone* @return*/@GetMapping("/sendMsgByMysqlAndSpringIOC")public String sendMsgBySpringIOC(@RequestParam("strategyId") String strategyId,@RequestParam("stragegyType") String stragegyType,@RequestParam("phone") String phone) {MsgStrategy strategy = strategyContext.getStrategy(strategyId, stragegyType, MsgStrategy.class);if (strategy == null) {return "当前渠道已关闭或者不存在,请核实!";}return strategy.sendMsg(phone);}/*** 测试链接(聚合短信):*     http://localhost:8080/sendMsgByMysqlAndSpringIOC?strategyId=ali_pay&stragegyType=1&phone=123456*     http://localhost:8080/sendMsgByMysqlAndSpringIOC?strategyId=ali_pay&stragegyType=1&phone=123456*     http://localhost:8080/sendMsgByMysqlAndSpringIOC?strategyId=ali_pay&stragegyType=1&phone=123456** 测试链接(聚合支付):* http://localhost:8080/sendMsgByMysqlAndSpringIOC?strategyId=ali_pay&stragegyType=0&phone=123456*/
5.6. mapper扫描配置
package com.gblfy.config;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;@Configuration
@MapperScan("com.gblfy.mapper")
public class MybatisPlusConfig {}
5.7. 依赖
<!--mybatis-plus 持久化--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>
5.8. yml配置
server:port: 8080
spring:datasource:username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/design_pattern?useUnicode=true&characterEncoding=UTF-8
logging:level:com.gblfy.mapper: DEBUG
mybatis-plus:configuration:log-impl:mapper-locations: classpath:mappers/*.xml
5.9. 开源地址

https://gitee.com/gblfy/design-pattern

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

引领开源新风潮,阿里巴巴编程之夏第二期重磅来袭!

“唯有热爱&#xff0c;可抵岁月漫长”。 2020 年 5 月 25 日&#xff0c;阿里巴巴编程之夏&#xff08;Alibaba Summer of Code&#xff0c;以下简称 ASoC &#xff09;第二期正式上线&#xff0c;项目规模再度升级&#xff0c;来自开源社区的 Apache Dubbo、Apache RocketMQ…

powerdesigner逆向工程(sql转pdm)

第一步&#xff1a; File -> Reverse Engineer -> Database 第二步 &#xff1a; Using Script Files -> Add Files

安谋中国发布“玲珑”i3i5 ISP处理器,剑指何方?

随着图像视频处理技术的发展和 5G 时代的来临&#xff0c;除了社交等平台外&#xff0c;以图像、视频为载体的内容渗透到各领域&#xff0c;特别是智能安防、AIoT、智能汽车等新兴领域应用。与此同时&#xff0c;人们对其清晰度、图像分辨率有新的扩展需求&#xff0c;对摄像头…

凯度信息之美奖揭晓,数据可视化后有多“性感”?

前言&#xff1a;更多关于数智化转型、数据中台内容可扫码加群一起探讨 阿里云数据中台官网 https://dp.alibaba.com/index &#xff08;作者&#xff1a;常成&#xff09; 2019年的“凯度信息之美奖”揭晓了&#xff0c;有很多很有意思的信息可视化作品。很多作品看到的时候…

精讲23种设计模式-基于责任链模式~构建企业级风控系统

文章目录一、责任链1. 责任链基本概念2. 定义3. 关键要点4. 责任链模式优缺点5. 责任链模式类结构图6. 网关权限控制责任链模式二、构建企业级风控系统2.1. 定义公共抽象任务2.2. (失信名单)校验处理类2.3. (信用卡)逾期处理类2.4. (蚂蚁信用积分)处理类2.5. 责任链工厂(第一种…

mybatis报错:Could not find result map java.lang.Integer

异常原因&#xff1a; 返回值为Integer的语句&#xff0c;本应该是&#xff1a; resultType"java.lang.Integer"//正确写的是&#xff1a; resultMap"java.lang.Integer"//错误最坑的是别人的mapper写错&#xff0c;会影响全局哦&#xff0c;不一定是你…

说一说阿里云弹性公网IP那些事

弹性公网IP是独立的公网IP资源&#xff0c;可以绑定到阿里云专有网络VPC类型的ECS、NAT网关、私网负载均衡SLB上&#xff0c;并可以动态解绑&#xff0c;实现公网IP和ECS、NAT网关、SLB的解耦&#xff0c;满足灵活管理的要求。 弹性公网IP作为一种网络基础能力&#xff0c;也是…

抓取了《大秦赋》所有数据,我发现了这些秘密

本文由黄勇老师特约供稿学习人数超13万人的<Python入门到实战一卡通>作者网易、360、华为特约Python讲师前言最近大火的电视剧《大秦赋》&#xff0c;给朋友圈的小伙伴都拉回到那个风云激荡的春秋战国时期&#xff0c;大家都在热情的讨论着大秦一统&#xff0c;秦始皇嬴政…

org.apache.ibatis.reflection.ReflectionException: There is no getter for property named XXX

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named XXX 根本原因&#xff1a; mybatis 的xml中有的属性&#xff0c;在mapper传入的参数中找不到。 可能引起原因&…

精讲23种设计模式-基于观察者模式~设计异步多渠道群发框架

文章目录一、观察者模式1. 观察者模式基本概念2. 观察者模式的应用场景3. 观察者模式的类图二、设计异步多渠道群发框架2.1. 定义消息观察者抽象接口2.2. 创建观察者2.3. 主题通知所有观察者2.4. 观察者注册2.5. 自定义线程池2.6. 签单通知入口2.6. 异步通知接口测试2.7. 依赖三…

君子动手不动口,阿里云喊你做云上体验官啦!

想要免费搭建云上博客&#xff1f;想要玩转全云端开发&#xff1f;想要挑战AI经典命题&#xff1f;想要7天进阶成为云计算专家&#xff1f;想要初始化你的云原生工程&#xff1f;快来阿里云 Hands-on Labs&#xff01; Hands-on Labs 是阿里云全新推出的云上动手实验室&#x…

我是Redis,MySQL大哥被我害惨了!

来源 | 编程技术宇宙责编 | 晋兆雨头图 | 付费下载于视觉中国我是Redis你好&#xff0c;我是Redis&#xff0c;一个叫Antirez的男人把我带到了这个世界上。说起我的诞生&#xff0c;跟关系数据库MySQL还挺有渊源的。在我还没来到这个世界上的时候&#xff0c;MySQL过的很辛苦&a…

MySQLSyntaxErrorException: Every derived table must have its own alias

每个派生出来的表都必须有一个自己的别名 因为&#xff0c;进行嵌套查询的时候子查询出来的的结果是作为一个派生表来进行上一级的查询的&#xff0c;所以子查询的结果必须要有一个别名 把MySQL语句改成&#xff1a;select count(*) from (select * from ……) as total; 问…

联手友盟+打造云上数据增长“样板间”, 好兔视频成功逆势突围

前言&#xff1a;更多关于数智化转型、数据中台内容可扫码加群一起探讨 阿里云数据中台官网 https://dp.alibaba.com/index &#xff08;作者&#xff1a;友盟&#xff09; “消费升级”是近年来的中国消费市场热门词汇&#xff0c;消费升级的同时也驱动了内容消费升级。在这样…

SpringBoot 使用 Caffeine 本地缓存

文章目录一、本地缓存介绍二、缓存组件 Caffeine 介绍2.1. Caffeine 性能2.2. Caffeine 配置说明2.3. 软引用与弱引用三、SpringBoot 集成 Caffeine 方式一3.1. Maven 引入相关依赖3.2. 配置缓存配置类3.3. 定义实体对象3.4. 定义服务接口类3.5. 定义服务接口实现类3.6. Caffei…

《Istio 从懵圈到熟练:二分之一活的微服务》

作者 | 声东 阿里云售后技术专家 <关注阿里巴巴云原生公众号&#xff0c;回复 排查 即可下载电子书> 《深入浅出 Kubernetes》一书共汇集 12 篇技术文章&#xff0c;帮助你一次搞懂 6 个核心原理&#xff0c;吃透基础理论&#xff0c;一次学会 6 个典型问题的华丽操作…

为了追求更快,CPU、内存、I/O都做了哪些努力?

来源 | 编程技术宇宙责编 | 晋兆雨头图 | 付费下载于视觉中国背景曾经&#xff0c;我面试的时候有两个最怕的。一怕问算法&#xff0c;二怕问高并发。算法这个&#xff0c;自从刷了不少LeetCode&#xff0c;发现还是有套路可循的&#xff0c;虽不敢说算法能力有多强&#xff0c…

软件设计师 - 常用公式

流水线连续执行k段指令的时间&#xff1a; 流水线总时间 单条指令时间 流水线周期 * (k-1)或 流水线总时间 流水线周期 *k流水线周期为&#xff1a;指令分段执行中时间最长的一段&#xff08;先以第一个为主&#xff0c;算不出来&#xff0c;可用第二个&#xff09; 环路…

神结合!一招玩转K8s和微服务治理

发布会传送门 进入直播间还有好礼等你拿&#xff01; EDAS产品免费试用&#xff1a;https://www.aliyun.com/activity/middleware/edaspromotiononmay 首届云原生编程挑战赛正式开战&#xff01;立即报名瓜分330000现金奖&#xff1a;https://tianchi.aliyun.com/specials/p…

精讲23种设计模式-基于装饰模式~设计多级缓存框架

文章目录一、装饰模式1. 回顾多级缓存基本概念2. 装饰模式基本的概念3. 装饰模式应用场景4. 装饰者模式定义5. 基于Map手写Jvm内置缓存二、手写一级与二级缓存2.1. redis工具类2.2. 实体类2.3. 接口2.4. 数据库脚本2.5. 测试案例2.6. 测试效果分享三、设计多级缓存框架3.1. 缓存…