前言:“状态机”见名知意,用状态去管理业务操作,打个比方:0~1岁(出生状态),1~3岁(认知状态),3~6岁(启蒙状态),6~22岁(学习状态),22~60(工作状态),60以后(退休状态),那么人一生成长经历则是(状态跳转):出生状态  -> 认知状态  -> 启蒙状态  -> 学习状态 ->  工作状态  -> 退休状态.

在每个状态中都会有不同的经历(事件),每个年龄就去干每个年龄的事情,背负这个年龄应该背负的责任,同时也享有这个年龄相应的乐趣(不同的状态去做不同的事情),直到离开这个世界(状态销毁)。

人的一生不可以倒退,但是:状态机可以,它可以在每个状态间互相跳转去做不同的事情,这样的好处:逻辑清晰、可以适当的控制并发、使整个事物更加通畅,好了,上代码:

1.新建状态机的辅助类:因为spring内部在redis中维护了一个状态机的hash表,所以必须接入redis

  1. /*
  2. * o(-"-)o
  3. *
  4. * CopyRight(C) 2011 GameRoot Inc.
  5. *
  6. *
  7. *
  8. */
  9. package com.qty.arena.helper.match.room;
  10.  
  11. import javax.annotation.PostConstruct;
  12.  
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.data.redis.core.RedisTemplate;
  15. import org.springframework.messaging.Message;
  16. import org.springframework.messaging.support.MessageBuilder;
  17. import org.springframework.statemachine.StateMachine;
  18. import org.springframework.statemachine.service.StateMachineService;
  19. import org.springframework.stereotype.Component;
  20.  
  21. import com.qty.arena.core.ObjectReference;
  22. import com.qty.arena.room.match.statemachine.RoomMatchEvent;
  23. import com.qty.arena.room.match.statemachine.RoomMatchState;
  24.  
  25. /**
  26. * 队伍状态机持久化辅助类
  27. *
  28. *
  29. * @data 2018年1月31日 下午2:22:58
  30. */
  31. @Component
  32. public class RoomMatchStateMachineHelper {
  33.  
  34. // private static final Logger LOGGER = LoggerFactory.getLogger(TeamStateMachineHelper.class);
  35.  
  36. private static final ObjectReference<RoomMatchStateMachineHelper> ref = new ObjectReference<RoomMatchStateMachineHelper>();
  37.  
  38. /** 房间状态机参数传递通用DTO */
  39. public static final String ROOM_ACTION_DELIVERY_DTO = "room_action_delivery_dto";
  40.  
  41. // @Autowired
  42. // private StateMachinePersist<RoomState, RoomEvent, String> stateMachinePersist;
  43.  
  44. @Autowired
  45. private StateMachineService<RoomMatchState, RoomMatchEvent> roomMatchStateMachineService;
  46.  
  47. @Autowired
  48. private RedisTemplate<String, String> redisTemplate;
  49.  
  50. @PostConstruct
  51. void init() {
  52. ref.set(this);
  53. }
  54.  
  55. public static RoomMatchStateMachineHelper getInstance() {
  56. return ref.get();
  57. }
  58.  
  59. /**
  60. * 获取状态机
  61. *
  62. * @param machineId
  63. * 状态机编号
  64. * @return
  65. */
  66. public StateMachine<RoomMatchState, RoomMatchEvent> getStateMachine(String machineId) {
  67. return roomMatchStateMachineService.acquireStateMachine(machineId);
  68. }
  69.  
  70. // /**
  71. // * 存储状态
  72. // *
  73. // * @param machineId
  74. // * 状态机编号
  75. // * @throws Exception
  76. // */
  77. // public void save(String machineId) throws Exception {
  78. // StateMachineContext<RoomState, RoomEvent> stateMachineContext = stateMachinePersist.read(machineId);
  79. // stateMachinePersist.write(stateMachineContext, machineId);
  80. // }
  81.  
  82. /**
  83. * 删除状态机
  84. *
  85. * @param machineId
  86. * 状态机编号
  87. */
  88. public void delete(String machineId) {
  89. roomMatchStateMachineService.releaseStateMachine(machineId);
  90. redisTemplate.delete("RedisRepositoryStateMachine:" + machineId);
  91. }
  92.  
  93. /**
  94. * 普通状态转换事件
  95. *
  96. * @param machineId
  97. * 状态机编号
  98. * @param event
  99. * 事件
  100. */
  101. public StateMachine<RoomMatchState, RoomMatchEvent> sendEvent(String machineId, RoomMatchEvent event) {
  102. StateMachine<RoomMatchState, RoomMatchEvent> stateMachine = getStateMachine(machineId);
  103. if (stateMachine.sendEvent(event)) {
  104. return stateMachine;
  105. }
  106. return null;
  107. }
  108.  
  109. /**
  110. * 传参的状态转换事件
  111. *
  112. * @param machineId
  113. * 状态机编号
  114. * @param event
  115. * 事件
  116. * @param headerName
  117. * 传递参数的Key
  118. * @param object
  119. * 传递的参数:对象
  120. */
  121. public StateMachine<RoomMatchState, RoomMatchEvent> sendEvent(String machineId, RoomMatchEvent event, String headerName, Object object) {
  122. StateMachine<RoomMatchState, RoomMatchEvent> stateMachine = getStateMachine(machineId);
  123. Message<RoomMatchEvent> message = MessageBuilder
  124. .withPayload(event)
  125. .setHeader(headerName, object)
  126. .build();
  127. //传递参数的事件
  128. if (stateMachine.sendEvent(message)) {
  129. return stateMachine;
  130. }
  131. return null;
  132. }
  133. }

2.配置适配器

  1. /*
  2. * o(-"-)o
  3. *
  4. * CopyRight(C) 2011 GameRoot Inc.
  5. *
  6. */
  7. package com.qty.arena.room.custom.statemachine;
  8.  
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.context.annotation.Bean;
  11. import org.springframework.statemachine.config.EnableStateMachineFactory;
  12. import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
  13. import org.springframework.statemachine.config.StateMachineFactory;
  14. import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
  15. import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
  16. import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
  17. import org.springframework.statemachine.data.redis.RedisPersistingStateMachineInterceptor;
  18. import org.springframework.statemachine.data.redis.RedisStateMachineRepository;
  19. import org.springframework.statemachine.persist.StateMachineRuntimePersister;
  20. import org.springframework.statemachine.service.DefaultStateMachineService;
  21. import org.springframework.statemachine.service.StateMachineService;
  22.  
  23. import com.qty.arena.room.custom.statemachine.action.RoomCustomAlreadyDestroyEntryAction;
  24. import com.qty.arena.room.custom.statemachine.action.RoomCustomAlreadySettlementEntryAction;
  25. import com.qty.arena.room.custom.statemachine.action.RoomCustomCreateEntryAction;
  26. import com.qty.arena.room.custom.statemachine.action.RoomCustomCreateLolInEntryAction;
  27. import com.qty.arena.room.custom.statemachine.action.RoomCustomStartedEntryAction;
  28. import com.qty.arena.room.custom.statemachine.action.RoomCustomVoteInEntryAction;
  29.  
  30. /**
  31. * 房间有限状态机适配器
  32. *
  33. *
  34. * @data 2018年1月27日 上午10:30:42
  35. */
  36. @EnableStateMachineFactory(name = "roomCustomStateMachineFactory")
  37. public class RoomCustomStateMachineConfig extends EnumStateMachineConfigurerAdapter<RoomCustomState, RoomCustomEvent> {
  38.  
  39. @Autowired
  40. private RedisStateMachineRepository redisStateMachineRepository;
  41.  
  42. @Autowired
  43. private RoomCustomCreateEntryAction roomCustomCreateEntryAction;
  44.  
  45. @Autowired
  46. private RoomCustomCreateLolInEntryAction roomCustomCreateLolInEntryAction;
  47.  
  48. @Autowired
  49. private RoomCustomStartedEntryAction roomCustomStartedEntryAction;
  50.  
  51. @Autowired
  52. private RoomCustomVoteInEntryAction roomCustomVoteInEntryAction;
  53.  
  54. @Autowired
  55. private RoomCustomAlreadyDestroyEntryAction roomCustomAlreadyDestroyEntryAction;
  56.  
  57. @Autowired
  58. private RoomCustomAlreadySettlementEntryAction roomCustomAlreadySettlementEntryAction;
  59.  
  60. @Bean("roomCustomStateMachinePersist")
  61. public StateMachineRuntimePersister<RoomCustomState, RoomCustomEvent, String> stateMachinePersist() {
  62. return new RedisPersistingStateMachineInterceptor<RoomCustomState, RoomCustomEvent, String>(
  63. redisStateMachineRepository);
  64. }
  65.  
  66. @Bean("roomCustomStateMachineService")
  67. public StateMachineService<RoomCustomState, RoomCustomEvent> stateMachineService(
  68. StateMachineFactory<RoomCustomState, RoomCustomEvent> stateMachineFactory) {
  69. return new DefaultStateMachineService<RoomCustomState, RoomCustomEvent>(stateMachineFactory,
  70. stateMachinePersist());
  71. }
  72.  
  73. @Override
  74. public void configure(StateMachineConfigurationConfigurer<RoomCustomState, RoomCustomEvent> config)
  75. throws Exception {
  76. config.withPersistence().runtimePersister(stateMachinePersist());
  77.  
  78. config.withMonitoring().monitor(new RoomCustomStateMachineMonitor());
  79. }
  80.  
  81. @Override
  82. public void configure(StateMachineStateConfigurer<RoomCustomState, RoomCustomEvent> states) throws Exception {
  83. states.withStates()
  84. // 定义初始状态
  85. .initial(RoomCustomState.UNCREATED)
  86. // 定义状态机状态
  87.  
  88. /** 已创建db房间状态 */
  89. .state(RoomCustomState.CREATED_DB_STATE, roomCustomCreateEntryAction, null)
  90.  
  91. /** 创建Lol房间中状态 */
  92. .state(RoomCustomState.CREATE_LOL_IN, roomCustomCreateLolInEntryAction, null)
  93.  
  94. /** 已开局状态 */
  95. .state(RoomCustomState.STARTED, roomCustomStartedEntryAction, null)
  96.  
  97. /** 投票中状态 */
  98. .state(RoomCustomState.VOTE_IN, roomCustomVoteInEntryAction, null)
  99.  
  100. /** 自定义房间已结算状态 */
  101. .state(RoomCustomState.ALREADY_SETTLEMENT, roomCustomAlreadySettlementEntryAction, null)
  102.  
  103. /** 房间已销毁 */
  104. .state(RoomCustomState.ALREADY_DESTROY, roomCustomAlreadyDestroyEntryAction, null);
  105.  
  106. // .states(EnumSet.allOf(RoomState.class));
  107. }
  108.  
  109. @Override
  110. public void configure(StateMachineTransitionConfigurer<RoomCustomState, RoomCustomEvent> transitions)
  111. throws Exception {
  112.  
  113. transitions
  114.  
  115. // 初始化状态 -> 已创建 = 创建房间
  116. .withExternal()
  117. .source(RoomCustomState.UNCREATED)
  118. .target(RoomCustomState.CREATED_DB_STATE)
  119. .event(RoomCustomEvent.CREATE)
  120. .and()
  121.  
  122. // 已创建 -> 已销毁 = 退出(最后一人)
  123. .withExternal()
  124. .source(RoomCustomState.CREATED_DB_STATE)
  125. .target(RoomCustomState.ALREADY_DESTROY)
  126. .event(RoomCustomEvent.DESTROY_ROOM_CUSTOM)
  127. .and()
  128.  
  129. // 已创建 -> 已准备 = 全部准备
  130. .withExternal()
  131. .source(RoomCustomState.CREATED_DB_STATE)
  132. .target(RoomCustomState.CREATE_LOL_IN)
  133. .event(RoomCustomEvent.PREPARED_ALL)
  134. .and()
  135.  
  136. // 创建Lol房间中状态 -> 已创建 = 创建lol房间定时任务3分钟
  137. .withExternal()
  138. .source(RoomCustomState.CREATE_LOL_IN)
  139. .target(RoomCustomState.CREATED_DB_STATE)
  140. .event(RoomCustomEvent.CREATE_LOL_ROOM_TASK)
  141. .and()
  142.  
  143. // 创建lol房间中-> 已创建 = 退出
  144. .withExternal()
  145. .source(RoomCustomState.CREATE_LOL_IN)
  146. .target(RoomCustomState.CREATED_DB_STATE)
  147. .event(RoomCustomEvent.SIGN_OUT)
  148. .and()
  149.  
  150. // 创建lol房间中 -> 已开局 = 已创建LOL房间
  151. .withExternal()
  152. .source(RoomCustomState.CREATE_LOL_IN)
  153. .target(RoomCustomState.STARTED)
  154. .event(RoomCustomEvent.GAME_ROOM_HAS_BEEN_CREATED)
  155. .and()
  156.  
  157. // 已开局 -> 投票中 = 开始投票(6分钟)
  158. .withExternal()
  159. .source(RoomCustomState.STARTED)
  160. .target(RoomCustomState.VOTE_IN)
  161. .event(RoomCustomEvent.START_VOTE)
  162. .and()
  163.  
  164. // 投票中 -> 已创建 = 全部投票
  165. .withExternal()
  166. .source(RoomCustomState.VOTE_IN)
  167. .target(RoomCustomState.CREATED_DB_STATE)
  168. .event(RoomCustomEvent.ALL_VOTE)
  169. .and()
  170.  
  171. // 投票中 -> 已创建 = 全部投票
  172. .withExternal()
  173. .source(RoomCustomState.STARTED)
  174. .target(RoomCustomState.CREATED_DB_STATE)
  175. .event(RoomCustomEvent.ALL_VOTE)
  176. .and()
  177.  
  178. //投票中 -> 已创建 = 结算延时任务(2小时)
  179. .withExternal()
  180. .source(RoomCustomState.VOTE_IN)
  181. .target(RoomCustomState.CREATED_DB_STATE)
  182. .event(RoomCustomEvent.SETTLEMENT_DELAY_TASK)
  183. .and()
  184.  
  185. //投票中 -> 已结算 = 投票结算
  186. .withExternal()
  187. .source(RoomCustomState.VOTE_IN)
  188. .target(RoomCustomState.ALREADY_SETTLEMENT)
  189. .event(RoomCustomEvent.VOTE_SETTLEMENT)
  190. .and()
  191.  
  192. //投票中 -> 已结算 = 查询结算
  193. .withExternal()
  194. .source(RoomCustomState.VOTE_IN)
  195. .target(RoomCustomState.ALREADY_SETTLEMENT)
  196. .event(RoomCustomEvent.QUERY_SETTLEMENT)
  197. .and()
  198.  
  199. //投票中 -> 已结算 = 投票取消比赛(退还所有人蜜汁)
  200. .withExternal()
  201. .source(RoomCustomState.VOTE_IN)
  202. .target(RoomCustomState.ALREADY_SETTLEMENT)
  203. .event(RoomCustomEvent.VOTE_RETURN_MONEY)
  204. .and()
  205.  
  206. //已开局 -> 已结算 = 投票取消比赛(退还所有人蜜汁)
  207. .withExternal()
  208. .source(RoomCustomState.STARTED)
  209. .target(RoomCustomState.ALREADY_SETTLEMENT)
  210. .event(RoomCustomEvent.VOTE_RETURN_MONEY)
  211. .and()
  212.  
  213. //已结算 -> 已创建 = 全部投票
  214. .withExternal()
  215. .source(RoomCustomState.ALREADY_SETTLEMENT)
  216. .target(RoomCustomState.CREATED_DB_STATE)
  217. .event(RoomCustomEvent.ALL_VOTE)
  218. .and()
  219.  
  220. //已结算 -> 已创建 = 结算延时任务(2小时)
  221. .withExternal()
  222. .source(RoomCustomState.ALREADY_SETTLEMENT)
  223. .target(RoomCustomState.CREATED_DB_STATE)
  224. .event(RoomCustomEvent.SAVE_RECORD_DELAY_TASK)
  225. .and()
  226. ;
  227. }
  228. }

3.Action

  1. package com.qty.arena.room.custom.statemachine.action;
  2.  
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.statemachine.StateContext;
  5. import org.springframework.statemachine.action.Action;
  6. import org.springframework.stereotype.Component;
  7.  
  8. import com.qty.arena.dto.RoomCustomActionDeliveryDTO;
  9. import com.qty.arena.helper.custom.room.RoomCustomCreateLolTaskHelper;
  10. import com.qty.arena.helper.custom.room.RoomCustomSignOutHelper;
  11. import com.qty.arena.helper.custom.room.RoomCustomStateMachineHelper;
  12. import com.qty.arena.helper.custom.room.RoomCustomVoteReturnRoomHelper;
  13. import com.qty.arena.room.custom.statemachine.RoomCustomEvent;
  14. import com.qty.arena.room.custom.statemachine.RoomCustomState;
  15.  
  16. /**
  17. * 已创建db房间状态
  18. *
  19. * @author yanLong.Li
  20. * @date 2018年11月10日 下午8:28:37
  21. */
  22. @Component
  23. public class RoomCustomCreateEntryAction implements Action<RoomCustomState, RoomCustomEvent> {
  24.  
  25. @Autowired
  26. private RoomCustomCreateLolTaskHelper roomCustomCreateLolTaskHelper;
  27.  
  28. @Autowired
  29. private RoomCustomSignOutHelper roomCustomSignOutHelper;
  30.  
  31. @Autowired
  32. private RoomCustomVoteReturnRoomHelper roomCustomVoteReturnRoomHelper;
  33.  
  34. @Override
  35. public void execute(StateContext<RoomCustomState, RoomCustomEvent> context) {
  36. Object object = context.getMessageHeader(RoomCustomStateMachineHelper.ROOM_ACTION_DELIVERY_DTO);
  37. if (!(object instanceof RoomCustomActionDeliveryDTO)) {
  38. return;
  39. }
  40. RoomCustomEvent event = context.getEvent();
  41. RoomCustomActionDeliveryDTO roomCustomActionDeliveryDTO = (RoomCustomActionDeliveryDTO) object;
  42. logic(roomCustomActionDeliveryDTO, event);
  43. }
  44.  
  45. private void logic(RoomCustomActionDeliveryDTO roomCustomActionDeliveryDTO , RoomCustomEvent event) {
  46. if(event == RoomCustomEvent.CREATE_LOL_ROOM_TASK) {
  47. roomCustomCreateLolTaskHelper.createLolTask(roomCustomActionDeliveryDTO);
  48. }/*else if(event == RoomCustomEvent.SETTLEMENT_DELAY_TASK) {
  49. RoomCustomDTO roomCustomDTO = roomCustomActionDeliveryDTO.getRoomCustomDTO();
  50. roomCustomHelper.settlementAndSaveRecord(roomCustomDTO);
  51. }else if(event == RoomCustomEvent.SAVE_RECORD_DELAY_TASK) {
  52. RoomCustomDTO roomCustomDTO = roomCustomActionDeliveryDTO.getRoomCustomDTO();
  53. roomCustomHelper.saveRecord(roomCustomDTO);
  54. }*/else if(event == RoomCustomEvent.SIGN_OUT) {
  55. roomCustomSignOutHelper.preparedSignOut(roomCustomActionDeliveryDTO);
  56. }else if(event == RoomCustomEvent.ALL_VOTE) {
  57. roomCustomVoteReturnRoomHelper.execute(roomCustomActionDeliveryDTO);
  58. }
  59. }
  60. }

4.演示调用

  1. TeamMatchStateMachineHelper.getInstance().sendEvent(teamMatch.getStateMachineId(), TeamMatchEvent.CREATE
  2. , TeamMatchStateMachineHelper.TEAM_ACTION_DELIVERY, TeamMatchActionDeliveryDTO.valueOf(teamMatch, arena.getId()));

spring 状态机的更多相关文章

  1. 彻底搞懂Spring状态机原理,实现订单与物流解耦

    本文节选自<设计模式就该这样学> 1 状态模式的UML类图 状态模式的UML类图如下图所示. 2 使用状态模式实现登录状态自由切换 当我们在社区阅读文章时,如果觉得文章写得很好,我们就会评 ...

  2. 01-项目简介Springboot简介入门配置项目准备

    总体课程主要分为4个阶段课程: ------------------------课程介绍------------------------ 01-项目简介Springboot简介入门配置项目准备02-M ...

  3. 花了30天才肝出来,史上最全面Java设计模式总结,看完再也不会忘

    本文所有内容均节选自<设计模式就该这样学> 序言 Design Patterns: Elements of Reusable Object-Oriented Software(以下简称&l ...

  4. Spring Boot 揭秘与实战(七) 实用技术篇 - StateMachine 状态机机制

    文章目录 1. 环境依赖 2. 状态和事件 2.1. 状态枚举 2.2. 事件枚举 3. 状态机配置4. 状态监听器 3.1. 初始化状态机状态 3.2. 初始化状态迁移事件 5. 总结 6. 源代码 ...

  5. Spring Boot - StateMachine状态机

    是Spring Boot提供的状态机的现成实现. 理论(有点像工作流) 需要定义一些状态的枚举,以及一些引起状态变化的事件的枚举. 每个状态可以对应的创建一个继承自org.springframewor ...

  6. 通过spring statemmachine 自定义构建属于自己的状态机(两种方式)

    spring 的stateMachine 相对于当前的版本,还是比较新颖的,但是对于合适的业务场景,使用起来还是十分的方便的.但是对于官网提供的文档,讲解的是十分的精简,要想更深入的了解其内部架构,只 ...

  7. 使用Spring StateMachine框架实现状态机

    spring statemachine刚出来不久,但是对于一些企业的大型应用的使用还是十分有借鉴意义的. 最近使用了下这个,感觉还是挺好的. 下面举个例子来说下吧: 创建一个Spring Boot的基 ...

  8. Spring web应用最大的败笔

    第一篇 介绍下IOC DI Spring主要是业务层框架,现在已经发展成为一个完整JavaEE开发框架,它的主要特点是IoC DI和AOP等概念的融合,强项在面向切面AOP.推出之初因为Ioc/AOP ...

  9. Spring Boot 1.5.x 基础学习示例

    一.为啥要学Spring Boot? 今年从原来.Net Team“被”转到了Java Team开始了微服务开发的工作,接触了Spring Boot这个新瓶装旧酒的技术,也初步了解了微服务架构.Spr ...

随机推荐

  1. 遭遇:“传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确” 错误

    http://www.cnblogs.com/delphinet/archive/2010/03/09/1681777.html 正在写一个类似文章的发表系统.其中记录文章内容的字段Contents设 ...

  2. 分布式系统登录功能拦截器的实现以及cookie的共享问题(利用cookie实现session在分布式系统的共享)

    当我们的网站采用分布式部署系统时,每个子系统拥有自己独立的session,如果不实现session共享,当用户切换系统访问的时候,会不停的提示登录,这对于用户体验是非常不好的.因此对于多个子系统的的访 ...

  3. mysql数据库给局域网用户所有的权限

    ERROR 1698 (28000): Access denied for user 'root'@'localhost' 刚装好的服务端时必须用 sudo命令才能登录,不然就报1698的错误 然后就 ...

  4. 构造代码块----java基础总结

    前言:之前一直不知道构造代码块的意思是什么,只是知道他的具体的表现形式,因为经常在面试题中看到,所以准备好好写写. 作用: 给对象进行初始化,对象一建立就运行,而且优于构造方法运行. 和构造方法的区别 ...

  5. 鸟哥的Linux私房菜——第十四章:Bash Shell

    视频链接:http://www.bilibili.com/video/av10094012/ 本章目录: 1. Bash shell1.1 什么是 shell ? (我们通过shell与Kernel核 ...

  6. npm install --save

    1. npm install:本地安装 2. npm install -g:全局安装 我们在使用 npm install 安装模块或插件时,有两种命令把它们写入到 package.json 文件中去, ...

  7. Spring MVC 中 @ModelAttribute 注解的妙用

    Spring MVC 中 @ModelAttribute 注解的妙用 Spring MVC 提供的这种基于注释的编程模型,极大的简化了 web 应用的开发.其中 @Controller 和 @Rest ...

  8. .NET面试题系列(三)排序算法

    冒泡排序 , , , , , 7, 2, 4 }; //外层循环控制排序趟数 ; i < arr.Length - ; i++) { //内层循环控制每一趟排序多少次 ; j < arr. ...

  9. python中的__call__

    如果python中的一个类定义了 __call__ 方法,那么这个类它的实例就可以作为函数调用,也就是实现了 () 运算符,即可调用对象协议 下面是一个简单的例子: class TmpTest: de ...

  10. Redis常见操作命令

    1.库相关 select 索引 => 选择库 dbsize => 查询当前库中Key的数量 flushdb => 清空当前库 flushall => 清空所有库(建议不要用,除 ...