1. SpringBoot缓存(Ehcache)
(3)如果我们想要自定 Ehcache 配置文件的名称和位置,可以在 application.properties 中添加如下配置:
执行结果下如下:
可以看到第一次从DB查询了数据,第二次则从缓存读取,当更新DB数据时同时也更新了缓存数据,再次取数据仍然走缓存。
对于高频数据,一般希望长时间缓存,对于临时数据,如验证码,token等,一般需要一个指定的时间,到期则取消。
可以通过一个类去控制缓存的有效时间,一般指定 timeToIdleSeconds=0 表示数据一直有效, timeToLiveSeconds=X秒 指定过期时间,如下:
然后在controller灵活的调用
对于无状态的系统,可以方便的缓存token,验证码等短时有效的数据,方便存取。
2. springboot开启Cache缓存
一、Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache ,ConcurrentMapCache等;
每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结码带果后返回给用户。下次调用直接从缓存中获取。
使用Spring缓存抽象时我们需要关注以下两点;
1、确定方法需要被缓存以及他们的缓存策略
2、从缓存模袜中读取之前缓存存储的数据
二、注意:
1.当我们要使用root对象的属性作为key时我们也可以将“#root”省略,迟码芦因为Spring默认使用的就是root对象的属性。 如
@Cacheable(key = "targetClass + methodName +#p0")
2.使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。 如:
@Cacheable(value="users", key="#id")
@Cacheable(value="users", key="#p0")
三、使用
1.依赖
2.启动类注解@EnableCaching开启缓存
3.缓存@Cacheable
@Cacheable注解会先查询是否已经有缓存,有会使用缓存,没有则会执行方法并缓存。
参考 https://www.cnblogs.com/yueshutong/p/9381540.html
3. SpringBoot整合SpringSeesion实现Redis缓存
使用Spring Boot开发项目时我们经常需要存储Session,因为Session中会存一些用户信息或者登录信息。传统的web服务是将session存储在内存中的,一旦服务挂了,session也就消失了,这时候我们就需要将session存储起来,而Redis就是用来缓存seesion的一种非关系型数据库,我们可以通过配置或者注解的方式将Spring Boot和Redis整合。而在分布式系统中又会涉及到session共享的问题,多个服务同时部署时session需要共享,Spring Session可以帮助我们实现这一功能。将Spring Session集成到Spring Boot框架中并使用Redis进行缓存是目前非常流行的解决方案,接下来就跟着我一起学习吧。
工具/材料
IntelliJ IDEA
首先我们创建一个Spring Boot 2.x的项目,在application.properties配置文件中添加Redis的配置,Spring和Redis的整合可以参考我其他的文章,此处不再详解。我们设置服务端口server.port为8080端口用于启动第一个服务。
接下来我们需要在pom文件中添加spring-boot-starter-data-redis和spring-session-data-redis这两个依赖,spring-boot-starter-data-redis用于整合Spring Boot和Redis,spring-session-data-redis集成了spring-session和spring-data-redis,提供了session与redis的整合方案。
接下来我们创建一个配置类RedisSessionConfig,这个类使用@Configuration注解表明这是一个配置类。在这个类上我们同时添加注解@EnableRedisHttpSession,表示开启Redis的Session管理。如果需要设置失效时间可以使用@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)表示一小时后失效。若同时需要设置Redis的命名空间则使用@EnableRedisHttpSession(maxInactiveIntervalInSeconds=3600, redisNamespace="{spring.session.redis.namespace}") ,其中{spring.session.redis.namespace}表示从配置文件中读取这个命名空间。
配置完成后我们写一个测试类SessionController,在这个类中我们写两个方法,一个方法用于往session中存数据,一个用于从session中取数据,代码如下图所示,我们存取请求的url。启动类非常简单,一般都是通用的,我们创建一个名为SpringbootApplication的启动类,使用main方法启动。
接下来我们使用Postman分别请求上面两个接口,先请求存数据接口,再请求取数据接口,结果如下图所示,我们可以看到数据已从redis中取出。另外需要注意sessionId的值,这是session共享的关键。
为了验证两个服务是否共享了session,我们修改项目的配置文件,将服务端口server.port改为8090,然后再启动服务。此时我们不必在请求存数据的接口,只需要修改请求端口号再一次请求取数据的接口即可。由下图可以看到两次请求的sessionId值相同,实现了session的共享。
以上我们完成了SpringBoot整合SpringSeesion实现Redis缓存的功能,在此我们还要推荐一个Redis的可视化工具RedisDesktopManager,我们可以配置Redis数据库的连接,然后便可以非常直观地查看到存储到Redis中的session了,如下图所示,session的命名空间是share,正是从配置文件中读取到的。
特别提示
如果Redis服务器是很多项目共用的,非常建议配置命名空间,否则同时打开多个项目的浏览器页面可能会导致session错乱的现象。
4. Spring boot + Mybatis plus + Redis实现二级缓存
1.1 通过application.yml配置redis的连接信息,springboot默认redis用的lecttuce客户端,如果想用jedis的话,只需要在pom.xml中引入redis的时候排除在lecttuce,然后再导入jedis的jar包就好了,
1.2 打开mybatis plus的二级缓存,为true的时候是开启的,false是关闭二级缓存
1.3 编写缓存类继承Cache类,实现Cache中的方法
1.4 早*.xml中加上<cache>标签,type写你所编写二级缓存类的路径
5. Spring本地缓存的使用方法
我们现在在用的Spring Cache,可以直接看Spring Boot提供的缓存枚举类,有如下这些:
EhCache:一个纯Java的进程内缓存框架,所以也是基于本地缓存的。(注意EhCache2.x和EhCache3.x相互不兼容)。
Redis:分布式缓存,只有Client-Server(CS)模式,Java一般使用Jedis/Luttuce来操纵。
Hazelcast:基于内存的数据网格。虽然它基于内存,但是分布式应用程序可以使用Hazelcast进行分布式缓存、同步、集群、处理、发布/订阅消息等。
Guava:它是Google Guava工具包中的一个非常方便易用的本地化缓存实现,基于LRU(最近最少使用)算法实现,支持多种缓存过期策略。在Spring5.X以后的版本已经将他标记为过期了。
Caffeine:是使用Java8对Guava缓存的重写版本,在Spring5中将取代了Guava,支持多种缓存过期策略。
SIMPLE:使用ConcurrentMapCacheManager,因为不支持缓存过期时间,所以做本地缓存基本不考虑该方式。
关于分布式缓存,我们需要后面会专门讨论Redis的用法,这里只看本地缓存。性能从高到低,依次是Caffeine,Guava,ConcurrentMapCacheManager,其中Caffeine在读写上都快了Guava近一倍。
这里我们只讨论在Spring Boot里面怎么整合使用Caffeine和EhCache。
主要有以下几个步骤:
1)加依赖包:
2)配置缓存:
这里有两种方法,通过文件配置或者在配置类里面配置,先看一下文件配置,我们可以写一个properties文件,内容像这样:
然后还要在主类中加上@EnableCaching注解:
另外一种更灵活的方法是在配置类中配置:
应用类:
测试类:
导入依赖包,分为2.x版本和3.x版本。
其中2.x版本做如下导入:
3.x版本做如下导入:
导包完成后,我们使用JCacheManagerFactoryBean + ehcache.xml的方式配置:
参考资料:
https://blog.csdn.net/f641385712/article/details/94982916
http://www.360doc.com/content/17/1017/20/16915_695800687.shtml
6. Spring Boot Cache - 本地缓存
pom.xml
使用Spring Boot Cache框架,其中一个很大的好处,就是可以很猜改方便的枝返更换缓存实现
Spring Boot会检查class path里的类,发现合适的(比如caffeine)就会生成对应猛兆饥的 CacheManager
application.properties
7. springboot @Cacheable 基本使用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
@Cacheable :
对方法结果进行缓存(主要用于GET方法)
cacheNames/value:指定缓存主键(Cache)的名字
key:缓存数据使用key,支持spEl语法
keyGenerator:key的生成器。与key属性冲突,自定义 keyGenerator 必须实现
org.springframework.cache.interceptor.KeyGenerator,default使用默认的参数值生成器
cacheManager:指定缓存管理器,或者cacheResolver指定获取解析器cacheResolver:与
CacheManager冲突condition:指定条件满足才缓存,与unless相反。可以使用spEL语法
unless:否定缓存,当满足条件时,结果不被缓存。可以获取到结果(#result)进行判断。支持spEL语法
sync:是否异步模式。在该模式下unless不被支持。default=false
@CachePut:先调用方法,在对结果进行缓存。(主要用于PUT方法),需要注意key的设置@CacheEvict:默认先调用方法,在删除缓存(主要用于DELETE方法)allEntries: 删除缓存组件中(cacheNames/value指定)所有的值beforeInvocation:在方法执行之前删除值,default=false@Caching:组合注解。针对复杂情况@CacheConfig:加载类上,用于设置缓存的共有属纤好兆性
几个属性:
cacheNames/values:指定缓存组件的名字,将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存
key:缓存数据使用毁租的key;袜稿可以用它来指定。默认是使用方法参数的值
可以用spEL表达式来表示;#id-如(getEmp[1]); 参数id的值: #a0 #p0 #root.args[0]
keyGenerator:key的生成器;可以自己指定key的生成器的组件id
key/keyGenerator:二选一使用(自己配置类)
cacheManager:指定使用哪个缓存管理器;或者cacheResolver指定获取解析器
condition:指定符合条件的情况下才缓存; 如:condition = "#a0>1" 即第一个参数值大于1时才进行缓存
unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到的结果进行判断
如: unless = “#a0”:如果第一个参数值是2,则结果不缓存 unless = “#result == null” 结果为null不缓存结合写法:
@Cacheable(cacheNames = {"emp"},keyGenerator = "myKeyGenerator",condition = "#a0>1",unless = "#a0==2") 意思为 放在的缓存名称为emp中,key的生成方式为配置的myKeyGenerator类,当第一个参数大于1时候缓存,当第一个参数等于2时不缓存
sync:是否使用异步模式(异步模式情况下unless不支持)
//@Cacheable(cacheNames = {"emp"},key = "#root.methodName+'['+#id+']'")
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
此时当id为1时,key的值为 getEmp[1]
@Configuration
public class MyCacheConfig {
@Bean("myKeyGenerator")
public KeyGenerator keyGenerator (){
return new KeyGenerator(){
@Override
public Object generate(Object o, Method method, Object... objects) {
return method.getName()+"["+ Arrays.asList(objects).toString()+"]";
}
};
};
}
这里返回的key的值为getEmp[[1]]
8. SpringBoot进阶之整合Shiro实现缓存和会话管理
大家好,一直以来我都本着用最通俗的话理解核心的知识点, 我认为所有的难点都离不开 “基础知识” 的铺垫。目前正在出一个 SpringBoot 长期系列教程,从入门到进阶, 篇幅会较多~
“大佬可以绕过 ~”
如果你是一路看过来的,很高兴你能够耐心看完。之前带大家学了 Springboot 基础部分,对基本的使用有了初步的认识, 接下来的几期内容将会带大家进阶使用,会先讲解基础 中间件 的使用和一些场景的应用,或许这些技术你听说过,没看过也没关系,我会带大家一步一步的入门,耐心看完你一定会有 收获 ~
上期带大家学习了 Shiro 中如何进行权限认证,本期将带大家学习 Shiro 中如何进行 缓存和会话管理 ,最后我们将做一个在线用户管理以及强制下线用户的功能,同样的,我们集成到 Springboot 中。
首先我们要明白使用缓存的原因,为啥要用它 还记得之前带大家实现的 用户认证 和 权限认证 吗,那里我使用了 MockUser ,真实场景中是要去数据查询的,这样一来就会产生耗时,请求多的时候数据库肯定忙不过来了,所以我们需要使用缓存来提高程序响应速度
缓存使用 Redis ,下面就带大家整一下:
修改 ShiroConfig ,添加方法
这样就可以了,大家可以把测试获取用户的地方改成数据库获取,看下 控制台 sql日志会明显减少,因为有一部分是从缓存拿的
这部分功能还是比较好玩的,学完可以自由发挥做一个房间功能,可以加入可以踢人,下面我们就开整
修改 ShiroConfig ,添加方法,因为我们使用的是 Redis 缓存
实现 SessionListener
最后同样的,想要开启需要我们注入到 Manager 中:
我们先定义一个类,用来记录在线用户:
那么怎么获取呢?我们定义一个方法,大家实践中可以抽到 Service 层,这里方便演示,我直接写到控制器里
如果你看谁不爽,可以直接让他下线,hhh~
是不是很简单,这里就不演示了,大家自行试试
本期内容就到这里结束了,总结一下,本节主要讲了 Shiro 如何进行缓存以及如何进行用户会话管理,大家可以举一反三,做一些小功能尝试尝试
下期给大家讲讲 Shiro 中如何整合 JWT ,这个大家应该不陌生,如果不知道啥是 JWT 也没关系,我会带大家一步一步入门,下期也是 Shiro 系列的终极篇,内容可能有点多,耐心看完哦。欢迎加群一起学习交流 ~
9. SpringBoot 操作 Redis的各种实现(Jedis、Redisson的区别比较)
共同点:都提供了基于Redis操作的Java API,只是封装程度,具体实现稍有不同。
不同点:
是Redis的Java实现的客户端。支汪模持基本的数据类型如:String、Hash、List、Set、Sorted Set。
特点:使用阻塞的I/O,方法调用同步,程序流需要等到socket处理完I/O才能执行,不支持异步操作。Jedis客户端实例不是线程安全的,需要通过连接池来使用Jedis。
优点点:分布式锁,分布式集合,可通过Redis支持延迟队列。
用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。
基于Netty框架的事件驱动的通信层,其方法调用是异步的。Lettuce的API是线程安全的,所以可以操作单个Lettuce连接来完成各种操作。
maven配置引入,(要加上版本号,我这里是因为Parent已声明)
application-dev.yml
redisson-config.yml
或者,配置 redisson-config.json
新建读取配置类银禅
或者,在 application.yml中配置如下
4.3.1 丰富的jar支持,尤其是对 Netty NIO框架
4.3.2 丰富的配置机制选择,这里是详细的配置说明
关于序列化机制中,就有很多
4.3.3 API支持(部分展示困搏缓),具体的 Redis --> RedissonClient ,可查看这里
4.3.4 轻便的丰富的锁机制的实现
参考 RedisTemplate 配置。
另外,还需要额外的配置类
基于spring缓存实现
10. 2022-03-12 SpringBoot 使用redis做缓存,设置失效时间以及序列化
SpringBoot的cache缓存,是针对返回值的一种操作
springboot使用redis做缓存时,默认只需要导入redis依赖,即可实现使用redis做缓存
不需要导入cache依赖
在启动类上加上 @EnableCaching 即可开启缓存功能
关于各个注解的使用,这里不再细说,网上详细的教程很多,这里主要讲一下如何指定过期时间
默认是永不过期,如果需要指定过期时间,则需要增加配置类