1. <?php
  2.  
  3. namespace App\Services;
  4.  
  5. use Illuminate\Support\Facades\Log;
  6. use Illuminate\Support\Facades\Redis;
  7.  
  8. class CacheDecorator
  9. {
  10. // 公司组织列表缓存key
  11. const COMPANY_ORGANIZE_KEY = 'company_organize_%s';
  12.  
  13. private static function setStringCacheStorage($key, $expireTime, string $data)
  14. {
  15. if ($expireTime) {
  16. Redis::setex($key, $expireTime, $data);
  17. } else {
  18. Redis::set($key, $data);
  19. }
  20. }
  21.  
  22. /**
  23. * 装饰器获取缓存数据
  24. * @param $cacheKey 缓存key
  25. * @param int $cacheTime 缓存时间
  26. * @param object $obj 对象
  27. * @param $method 缓存方法
  28. * @param mixed ...$args 参数
  29. * @return mixed
  30. */
  31. public static function getStringCache($cacheKey, $expireTime, object $obj, $method, ...$args)
  32. {
  33. try {
  34. $cacheData = Redis::get($cacheKey);
  35. $cacheData = json_decode($cacheData, true);
  36. if (empty($cacheData) || !isset($cacheData['org_data']) || empty($cacheData['org_data'])) {
  37. $cacheData = [
  38. 'org_data' => call_user_func_array([$obj, $method], $args)
  39. ];
  40. self::setStringCacheStorage($cacheKey, $expireTime, json_encode($cacheData, JSON_UNESCAPED_UNICODE));
  41. Log::info('从数据库获取数据', [
  42. 'class' => get_class($obj),
  43. 'method' => $method,
  44. 'args' => $args,
  45. ]);
  46. return $cacheData['org_data'];
  47. } else {
  48. Log::info('从缓存获取数据', [
  49. 'class' => get_class($obj),
  50. 'method' => $method,
  51. 'args' => $args,
  52. ]);
  53. return $cacheData['org_data'];
  54. }
  55. } catch (\Exception $e) {
  56. Log::error("redis缓存错误", [
  57. 'msg' => $e->getMessage(),
  58. 'line' => $e->getLine(),
  59. 'file' => $e->getFile(),
  60. ]);
  61. }
  62. Log::info('从数据库获取数据', [
  63. 'class' => get_class($obj),
  64. 'method' => $method,
  65. 'args' => $args,
  66. ]);
  67. return call_user_func_array([$obj, $method], $args);
  68. }
  69.  
  70. /**
  71. * 获取缓存key
  72. * @param $format
  73. * @param mixed ...$arg
  74. * @return string
  75. */
  76. public static function getCacheKey($format, ...$arg)
  77. {
  78. return sprintf($format, ...$arg);
  79. }
  80. }

调用

  1. public function listOrganize(AuthOrganizeService $authOrganizeService)
  2. {
  3. // before直接调用数据库
  4. $list = $authOrganizeService->listCompanyOrganize(Auth::user()->company_id);
  5. // after 直接使用缓存,但是listCompanyOrganize这个方法是没有进行任何的改动
  6. $list = CacheDecorator::getStringCache(
  7. CacheDecorator::getCacheKey(CacheDecorator::COMPANY_ORGANIZE_KEY),
  8. 100,
  9. AuthOrganizeService,
  10. 'listCompanyOrganize',
  11. 1
  12. );
  13. $res = [
  14. 'list' => $list,
  15. 'total' => 1 //不分页
  16. ];
  17. return $this->success($res);
  18. }

php使用装饰模式无侵入式加缓存的更多相关文章

  1. Hook 无侵入式埋点(页面统计)

    一.技术原理 Method-Swizzling 黑魔法 方法交换(不懂的可以查) 二.页面统计 某盟页面统计SDK需要开发者在APP基类里实现ViewDidAppear和viewDidDisappea ...

  2. Spring Boot 无侵入式 实现RESTful API接口统一JSON格式返回

    前言 现在我们做项目基本上中大型项目都是选择前后端分离,前后端分离已经成了一个趋势了,所以总这样·我们就要和前端约定统一的api 接口返回json 格式, 这样我们需要封装一个统一通用全局 模版api ...

  3. 使用AOP思想无侵入式申请权限,解决组件化中权限问题(一)

    首先介绍AspectJx使用 https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx 在根项目的build.gradle ...

  4. Android平台免Root无侵入AOP框架Dexposed使用详解

    Dexposed是基于久负盛名的开源Xposed框架实现的一个Android平台上功能强大的无侵入式运行时AOP框架. Dexposed的AOP实现是完全非侵入式的,没有使用任何注解处理器,编织器或者 ...

  5. Android新技术学习——阿里巴巴免Root无侵入AOP框架Dexposed

    阿里巴巴无线事业部近期开源的Android平台下的无侵入运行期AOP框架Dexposed,该框架基于AOP思想,支持经典的AOP使用场景.可应用于日志记录,性能统计,安全控制.事务处理.异常处理等方面 ...

  6. 小议webpack下的AOP式无侵入注入

    说起来, 面向切面编程(AOP)自从诞生之日起,一直都是计算机科学领域十分热门的话题,但是很奇怪的是,在前端圈子里,探讨AOP的文章似乎并不是多,而且多数拘泥在给出理论,然后实现个片段的定式)难免陷入 ...

  7. MVC的验证(模型注解和非侵入式脚本的结合使用) .Net中初探Redis .net通过代码发送邮件 Log4net (Log for .net) 使用GDI技术创建ASP.NET验证码 Razor模板引擎 (RazorEngine) .Net程序员应该掌握的正则表达式

    MVC的验证(模型注解和非侵入式脚本的结合使用)   @HtmlHrlper方式创建的标签,会自动生成一些属性,其中一些属性就是关于验证 如图示例: 模型注解 通过模型注解后,MVC的验证,包括前台客 ...

  8. Android沉浸式(侵入式)标题栏(状态栏)Status(一)

     Android沉浸式(侵入式)标题栏(状态栏)Status(一) 现在越来越多的APP设计采用这种称之为沉浸式状态栏(Status)的设计,这种沉浸式状态栏又称之"侵入式"状 ...

  9. 无侵入方面编程-用HttpModule+SoapExtension监视页面执行参数(二)

    上一篇文章 "无侵入方面编程-用HttpModule+SoapExtension监视页面执行参数(一)"中,我们实现了监视每个页面的执行情况和调用WebService的简单信息. ...

随机推荐

  1. Alpha个人项目测试

    这个作业属于哪个课程 [课程链接][ ] 这个作业要求在哪里 [作业要求][ ] 团队名称 [山海皆可平][ ] 作业目标 对其他小组进行测试 测试报告 姓名 唐友鑫 学号 201631062121 ...

  2. Java-ConfigHelper工具类

    /** * 读取配置文件 */ import java.io.File; import java.net.URL; import org.apache.commons.configuration.Co ...

  3. Java-JsonUtil工具类

    import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; i ...

  4. Oracle查询死锁

    select sample_time,session_id,sql_id,event,sql_plan_hash_value,blocking_session from dba_hist_active ...

  5. 基于node.js的websocket 前后端交互小功能

    一.node var ws = require("nodejs-websocket"); console.log("开始建立连接...") var server ...

  6. node压缩文件

  7. mysql随机取出n条数据

    SELECT * FROM  tableName  ORDER BY  RAND() LIMIT n      数据量小的话还可以, 数据量大起来了, 就影响性能了. $rubbish = (new ...

  8. ZOJ - 4045District Division dfs划分子树

    ZOJ - 4045District Division 题目大意:给你n个节点的树,然后让你划分这棵数使得,每一块都恰好k个节点并且两两间是连通的,也就是划分成n/k个连通集,如果可以输出YES,并输 ...

  9. noi.ac #534 猫

    题目链接:戳我 [问题描述] 有n座山,m只猫和p个工作人员.山从左往右编号为1∼n,山i和i−1之间的距离是di米. 有一天,猫都到山上去玩了:第i只猫会到山hi去,并一直玩到时间ti,之后就在那座 ...

  10. bootstrap面板的使用

    <div class="panel panel-primary"> <div class="panel-heading"> 头部 < ...