当前位置: 首页 > news >正文

做网站登录制作网站公司那家好

做网站登录,制作网站公司那家好,个人业务网站教程,空壳网站Why#xff1f; 为什么要对方法的返回值进行缓存呢#xff1f; 简单来说是为了提升后端程序的性能和提高前端程序的访问速度。减小对db和后端应用程序的压力。 一般而言#xff0c;缓存的内容都是不经常变化的#xff0c;或者轻微变化对于前端应用程序是可以容忍的。 否…Why 为什么要对方法的返回值进行缓存呢 简单来说是为了提升后端程序的性能和提高前端程序的访问速度。减小对db和后端应用程序的压力。 一般而言缓存的内容都是不经常变化的或者轻微变化对于前端应用程序是可以容忍的。 否则不建议加入缓存因为增加缓存会使程序复杂度增加还会出现一些其他的问题比如缓存同步数据一致性更甚者可能出现经典的缓存穿透、缓存击穿、缓存雪崩问题。 HowDo 如何缓存方法的返回值应该会有很多的办法本文简单描述两个比较常见并且比较容易实现的办法 自定义注解SpringCache annotation 整体思路 第一步定义一个自定义注解在需要缓存的方法上面添加此注解当调用该方法的时候方法返回值将被缓存起来下次再调用的时候将不会进入该方法。其中需要指定一个缓存键用来区分不同的调用建议为类名方法名参数名 第二步编写该注解的切面根据缓存键查询缓存池若池中已经存在则直接返回不执行方法若不存在将执行方法并在方法执行完毕写入缓冲池中。方法如果抛异常了将不会创建缓存 第三步缓存池首先需要尽量保证缓存池是线程安全的当然了没有绝对的线程安全。其次为了不发生缓存臃肿的问题可以提供缓存释放的能力。另外缓存池应该设计为可替代比如可以丝滑得在使用程序内存和使用redis直接调整。 MethodCache 创建一个名为MethodCache 的自定义注解 package com.ramble.methodcache.annotation; import java.lang.annotation.*;Documented Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD}) public interface MethodCache {} MethodCacheAspect 编写MethodCache注解的切面实现 package com.ramble.methodcache.annotation; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap;Slf4j Aspect Component public class MethodCacheAspect {private static final MapString, Object CACHE_MAP new ConcurrentHashMap();Around(value annotation(methodCache))public Object around(ProceedingJoinPoint jp, MethodCache methodCache) throws Throwable {String className jp.getSignature().getDeclaringType().getSimpleName();String methodName jp.getSignature().getName();String args String.join(,, Arrays.toString(jp.getArgs()));String key className : methodName : args;// key 示例DemoController:findUser:[FindUserParam(id1, namec7)]log.debug(缓存的key{}, key);Object cache getCache(key);if (null ! cache) {log.debug(走缓存);return cache;} else {log.debug(不走缓存);Object value jp.proceed();setCache(key, value);return value;}}private Object getCache(String key) {return CACHE_MAP.get(key);}private void setCache(String key, Object value) {CACHE_MAP.put(key, value);} } Around对被MethodCache注解修饰的方法启用环绕通知ProceedingJoinPoint通过此对象获取方法所在类、方法名和参数用来组装缓存keyCACHE_MAP缓存池生产环境建议使用redis等可以分布式存储的容器直接放程序内存不利于后期业务扩张后多实例部署 controller package com.ramble.methodcache.controller; import com.ramble.methodcache.annotation.MethodCache; import com.ramble.methodcache.controller.param.CreateUserParam; import com.ramble.methodcache.controller.param.FindUserParam; import com.ramble.methodcache.service.DemoService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*;Tag(name demo - api) Slf4j RequiredArgsConstructor RestController RequestMapping(/demo) public class DemoController {private final DemoService demoService;MethodCacheGetMapping(/{id})public String getUser(PathVariable(id) String id) {return demoService.getUser(id);}Operation(summary 查询用户)MethodCachePostMapping(/list)public String findUser(RequestBody FindUserParam param) {return demoService.findUser(param);} } 通过反复调用被MethodCache注解修饰的方法会发现若缓存池有数据将不会进入方法体。 SpringCache 其实SpringCache的实现思路和上述方法基本一致SpringCache提供了更优雅的编程方式更丝滑的缓存池切换和管理更强大的功能和统一规范。 EnableCaching 使用 EnableCaching 开启SpringCache功能无需引入额外的pom。 默认情况下缓存池将由 ConcurrentMapCacheManager 这个对象管理也就是默认是程序内存中缓存。其中用于存放缓存数据的是一个 ConcurrentHashMap源码如下 public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderAware {private final ConcurrentMapString, Cache cacheMap new ConcurrentHashMap(16);......} 此外可选的缓存池管理对象还有 EhCacheCacheManager JCacheCacheManager RedisCacheManager ...... Cacheable package com.ramble.methodcache.controller; import com.ramble.methodcache.controller.param.FindUserParam; import com.ramble.methodcache.service.DemoService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.*;Tag(name user - api) Slf4j RequiredArgsConstructor RestController RequestMapping(/user) public class UserController {private final DemoService demoService;Cacheable(value userCache)GetMapping(/{id})public String getUser(PathVariable(id) String id) {return demoService.getUser(id);}Operation(summary 查询用户)Cacheable(value userCache)PostMapping(/list)public String findUser(RequestBody FindUserParam param) {return demoService.findUser(param);} } 使用Cacheable注解修饰需要缓存返回值的方法value必填不然运行时报异常。类似一个分组将不同的数据或者方法当然也可以其他维度主要看业务需要放到一堆便于管理可以修饰接口方法但是不建议IDEA会报一个提示Spring doesnt recommend to annotate interface methods with Cache* annotation 常用属性 value缓存名称cacheNames缓存名称。value 和cacheNames都被AliasFor注解修饰他们互为别名key缓存数据时候的key默认使用方法参数的值可以使用SpEL生产keykeyGeneratorkey生产器。和key二选一cacheManager缓存管理器cacheResolver和caheManager二选一互为别名condition创建缓存的条件可用SpEL表达式如#id0表示当入参id大于0时候才缓存方法返回值unless不创建缓存的条件如#resultnull表示方法返回值为null的时候不缓存 CachePut 用来更新缓存。被CachePut注解修饰的方法在被调用的时候不会校验缓存池中是否已经存在缓存会直接发起调用然后将返回值放入缓存池中。 CacheEvict 用来删除缓存会根据key来删除缓存中的数据。并且不会将本方法返回值缓存起来。 常用属性 value/cacheeName缓存名称或者说缓存分组key缓存数据的键allEntries是否根据缓存名称清空所有缓存默认为false。当此值为true的时候将根据cacheName清空缓存池中的数据然后将新的返回值放入缓存beforeInvocation是否在方法执行之前就清空缓存默认为false Caching 此注解用于在一个方法或者类上面同时指定多个SpringCache相关注解。这个也是SpringCache的强大之处可以自定义各种缓存创建、更新、删除的逻辑应对复杂的业务场景。 属性 cacheable指定Cacheable注解put指定CachePut注解evict指定CacheEvict注解 源码 Target({ElementType.TYPE, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Inherited Documented public interface Caching {Cacheable[] cacheable() default {};CachePut[] put() default {};CacheEvict[] evict() default {}; } 相当于就是注解里面套注解用来完成复杂和多变的场景这个设计相当的哇塞。 CacheConfig 放在类上面那么类中所有方法都会被缓存 SpringCacheEnv SpringCache内置了一些环境变量可用于各个注解的属性中。 methodName被修饰方法的方法名 method被修饰方法的Method对象 target被修饰方法所属的类对象的实例 targetClass被修饰方法所属类对象 args方法入参是一个 object[] 数组 caches这个对象其实就是ConcurrentMapCacheManager中的cacheMap这个cacheMap呢就是一开头提到的ConcurrentHashMap即缓存池。caches的使用场景尚不明了。 argumentName方法的入参 result方法执行的返回值 使用示例 Cacheable(value userCache, condition #result!null,unless #resultnull) public String showEnv() { return 打印各个环境变量;} 表示仅当方法返回值不为null的时候才缓存结果这里通过result env 获取返回值。 另外condition 和 unless 为互补关系上述condition #result!null和unless #resultnull其实是一个意思。 Cacheable(value userCache, key #name) public String showEnv(String id, String name) {return 打印各个环境变量; } 表示使用方法入参作为该条缓存数据的key若传入的name为gg则实际缓存的数据为gg-打印各个环境变量 另外如果name为空会报异常因为缓存key不允许为null Cacheable(value userCache,key #root.args) public String showEnv(String id, String name) {return 打印各个环境变量; } 表示使用方法的入参作为缓存的key若传递的参数为id100namegg则实际缓存的数据为Object[]-打印各个环境变量Object[]数组中包含两个值。 既然是数组可以通过下标进行访问root.args[1] 表示获取第二个参数本例中即 取 name 的值 gg则实际缓存的数据为gg-打印各个环境变量。 Cacheable(value userCache,key #root.targetClass) public String showEnv(String id, String name) {return 打印各个环境变量; } 表示使用被修饰的方法所属的类作为缓存key实际缓存的数据为Class-打印各个环境变量key为class对象不是全限定名全限定名是一个字符串这里是class对象。 可是不是很懂这样设计的应用场景是什么...... Cacheable(value userCache,key #root.target) public String showEnv(String id, String name) {return 打印各个环境变量; } 表示使用被修饰方法所属类的实例作为key实际缓存的数据为UserController-打印各个环境变量。 被修饰的方法就是在UserController中调试的时候甚至可以获取到此实例注入的其它容器对象如userService等。 可是不是很懂这样设计的应用场景是什么...... Cacheable(value userCache,key #root.method) public String showEnv(String id, String name) {return 打印各个环境变量; } 表示使用Method对象作为缓存的key是Method对象不是字符串。 可是不是很懂这样设计的应用场景是什么...... Cacheable(value userCache,key #root.methodName) public String showEnv(String id, String name) {return 打印各个环境变量; } 表示使用方法名作为缓存的key就是一个字符串。 如何获取缓存的数据 ConcurrentMapCacheManager的cacheMap是一个私有变量所以没有办法可以打印缓存池中的数据不过可以通过调试的方式进入对象内部查看。如下 Tag(name user - api) Slf4j RequiredArgsConstructor RestController RequestMapping(/user) public class UserController {private final ConcurrentMapCacheManager cacheManager;/*** 只有调试才课可以查看缓存池中的数据*/GetMapping(/cache)public void showCacheData() {//需要debug进入CollectionString cacheNames cacheManager.getCacheNames();}} 总结 虽然提供了很多的环境变量但是大多都无法找到对应的使用场景其实在实际开发中最常见的就是key的生产一般而言使用类名方法名参数值足矣。
http://www.hkea.cn/news/14317382/

相关文章:

  • 网站做专题页面做网站虚拟主机和云服务器
  • 实现微信绑定登录网站陕西新站seo
  • 英迈思做网站怎么样哪个网站可以做兼职讲师
  • 网站维护运营怎么做新闻发稿平台
  • 济南行知网站建设有限公司怎么样wordpress导出图片不显示不出来
  • 域名空间网站建设做网站域名优化的怎么样
  • 做网站怎么把背景变成纯色自己做网站接入微信和支付宝
  • 深圳外贸企业网站建设微信朋友圈营销文案
  • 印刷建设网站高端品牌衣服
  • 外贸营销网站建设方案重庆市建设施工安全网
  • 四川德行天下建设工程有限公司网站做网站的行情
  • 企业网站栏目规划的重要性百度 验证网站
  • html转WordPress pageseo优化快排
  • 贵阳网络公司网站建设亮点云建站
  • 支付的网站建设费整么做账莱芜在线话题莱芜拉呱
  • 辽宁网站建设电话wordpress网站换空间
  • 网站 页面 结构wordpress怎么设置语言设置中文
  • 赤峰做网站多少钱报考二级建造师官网
  • 淮安建立公司网站流程2345浏览器网页版入口中文版
  • nodejs同时做网站和后台管理黑龙江住房城乡建设厅网站
  • 合肥响应式网站设计新乡市工程建设信息网
  • 通州做网站公司网站建设调研论文
  • 深圳模板建站代理外包公司辞退员工补偿标准
  • 宝安商城网站建设哪家便宜站内免费推广有哪些
  • 万网制作网站营销型网站盈利方案
  • 做网站推广方法有哪些哈尔滨专业做网站
  • 手机免费建站平台下载安卓开发环境搭建
  • 记事本怎么做网站图片链接广州网站制作有哪些
  • 网站开发要什么软件申请免费网站主页空间
  • 丹阳网站制作商旅平台app下载