目录
③使⽤springboot整合redis的专⽤客户端接⼝操作
5.使⽤xmemcached客户端操作缓存,注⼊MemcachedClient对象
6.1 SpringBoot内置缓存
springboot技术提供有内置的缓存解决⽅案,可以帮助开发者快速开启缓存技术,并使⽤缓存技术进⾏数据的快速操作。
步骤①:导⼊依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
步骤②:启⽤缓存
在引导类上⽅标注注解@EnableCaching配置springboot程序中可以使⽤缓存
@SpringBootApplication
@MapperScan("com.qfedu.dao")
@EnableCaching//开启内置缓存功能
public class Demo5SpringbootExampleApplication {
public static void main(String[] args) {
SpringApplication.run(Demo5SpringbootExampleApplication.class, args);
}
}
步骤③:修改Service的实现类
在Service的实现类CustomerServiceImpl添加@Cacheable注解缓存
@Override
@Cacheable(value = "cacheHome",key = "#identity")
public Customer findCustomerById(String identity) {
return customerMapper.findCustomerById(identity);
}
在业务⽅法上⾯使⽤注解@Cacheable声明当前⽅法的返回值放⼊缓存中,其中要指定缓存的存储位置,以及缓存中保存当前⽅法返回值对应的名称。上例中value属性描述缓存的存储位置,可以理解为是⼀个存储空间名,key属性描述了缓存中保存数据的名称。
使⽤@Cacheable注解后,执⾏当前操作,如果发现对应名称在缓存中没有数据,就正常读取数据,然后放⼊缓存;如果对应名称在缓存中有数据,就终⽌当前业务⽅法执⾏,直接返回缓存中的数据。
6.2 SpringBoot整合Redis
①导⼊springboot整合redis的starter
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
②进⾏基础配置
spring: redis: #端口(不配置默认为6379) port: 6379 #地址(不配置默认为localhost) host: localhost #密码 password: 123456
③使⽤springboot整合redis的专⽤客户端接⼝操作
此处使⽤的是RedisTemplate
@SpringBootTest
class Demo7SpringbootRedisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void setValue(){
ValueOperations operations = redisTemplate.opsForValue();
operations.set("username","zhangsanfeng");
}
@Test
void getValue(){
ValueOperations operations = redisTemplate.opsForValue();
Object username = operations.get("username");
System.out.println(username);
}
@Test
void setHashValue() {
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.put("msg","key","aaa");
}
@Test
void getHashValue() {
HashOperations hashOperations = redisTemplate.opsForHash();
Object o = hashOperations.get("msg", "key");
System.out.println(o);
}
}
在操作redis时,需要先确认操作何种数据,根据数据种类得到操作接⼝。例如使⽤opsForValue()获取string类型的数据操作接⼝,使⽤opsForHash()获取hash类型的数据操作接⼝,剩下的就是调⽤对应api操作了。
各种类型的数据操作接⼝如下:
redis内部不提供java对象的存储格式,因此当操作的数据以对象的形式存在时,会进⾏序列化转码。为了⽅便开发者使⽤基于字符串为数据的操作,springboot整合redis时提供了专⽤的API接⼝StringRedisTemplate,你可以理解为这是RedisTemplate的⼀种指定数据泛型的操作API。
@SpringBootTest
class RedisTests {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
void setValue(){
ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
operations.set("username","zhangsanfeng");
}
@Test
void getValue(){
ValueOperations<String,String> operations = stringRedisTemplate.opsForValue();
Object username = operations.get("username");
System.out.println(username);
}
@Test
void setHashValue() {
HashOperations<String, Object, Object> hashOperations = stringRedisTemplate.opsForHash();
hashOperations.put("msg","key","loading");
}
@Test
void getHashValue() {
HashOperations<String, Object, Object> hashOperations = stringRedisTemplate.opsForHash();
Object o = hashOperations.get("msg", "key");
System.out.println(o);
}
}
redis客户端选择
我们习惯⽤的客户端技术是jedis , 但是springBoot默认使⽤的是lettucs作为默认的客户端技术.
lettcus与jedis对⽐:
- jedis连接Redis服务器是直连模式,当多线程模式下使⽤jedis会存在线程安全问题,解决⽅案可以通过配置连接池使每个连接专⽤。
- lettcus基于Netty框架进⾏与Redis服务器连接,底层设计采⽤StatefulRedisConnection。 StatefulRedisConnection⾃身是线程安全的,可以保障并发访问安全问题,所以⼀个连接可以被多线程复⽤。
切换客户端为jedis
1.导⼊jedis坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
2.配置客户端技术类型,设置为jedis即可直接使用
spring: redis: #端口(不配置默认为6379) port: 6379 #地址(不配置默认为localhost) host: localhost #密码 password: 123456 #切换客户端 client-type: jedis jedis: pool: max-active: 10
redis中使⽤缓存
需求:⽣成4位数随机验证码,存再redis缓存中,再从缓存中获取数据,时效性为10秒。
步骤:
1. 导⼊redis坐标(之前操作过了)
2. 配置缓存技术实现使⽤redis
redis作为缓存使⽤相关的配置,⾪属于spring.cache.redis节点下,注意不要写错位置了。
spring: redis: #端口(不配置默认为6379) port: 6379 #地址(不配置默认为localhost) host: localhost #密码 password: 123456 #切换客户端 client-type: jedis cache: #修改缓存供应商 type: redis redis: #key是否使用前缀 use-key-prefix: false #key的前缀 key-prefix: #是否允许key的value值为null cache-null-values: true #缓存时效时间 time-to-live: 10s
3.编写controller
@RestController
@RequestMapping("/cache")
public class RedisController {
@Autowired
private RedisService redisService;
/**
* 生成code
* @return
*/
@GetMapping
public String createCode(){
String code = redisService.createCode("");
System.out.println(code);
return code;
}
@PostMapping
public String getCode(){
//从redis缓存中获取的,与service的返回值无关
String code = redisService.getCode("");
return code;
}
}
4.编写service
@Service
public class RedisService {
@CachePut(value = "codeMsg",key = "#code")//将生成的strCode放入key为code的缓存
public String createCode(String code) {
int max=10000;
int min=1000;
Random random=new Random();
String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
return strCode;
}
@Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
public String getCode(String code){
return null;
}
}
5.在引导类打开缓存
@SpringBootApplication
@EnableCaching//打开缓存开关
public class Demo7SpringbootRedisApplication {
public static void main(String[] args) {
SpringApplication.run(Demo7SpringbootRedisApplication.class, args);
}
}
总结
1. springboot使⽤redis作为缓存实现需要导⼊redis的坐标
2. 修改设置,配置缓存供应商为redis,并提供对应的缓存配置
6.3SpringBoot整合Ehcache
Ehcache
EhCache 是⼀个纯 Java 的进程缓存框架,具有快速、精⼲等特点,是 Hibernate 中默认CacheProvider。Ehcache 是⼀种⼴泛使⽤的开源 Java 分布式缓存。主要⾯向通⽤缓存,Java EE 和轻量级容器。
特性
- 快速、简单
- 多种缓存策略
- 缓存数据有两级:内存和磁盘,因此⽆需担⼼容量问题
- 缓存数据会在虚拟机重启的过程中写⼊磁盘
- 可以通过RMI、可插⼊API等⽅式进⾏分布式缓存
- 具有缓存和缓存管理器的侦听接⼝
- ⽀持多缓存管理器实例,以及⼀个实例的多个缓存区域
- 提供Hibernate的缓存实现
EhCache 与 Redis 相⽐
- EhCache 直接在jvm虚拟机中缓存,速度快,效率⾼;但是缓存共享麻烦,集群分布式应⽤不⽅便。
- Redis 是通过 Socket 访问到缓存服务,效率⽐ EhCache 低,⽐数据库要快很多,处理集群和分布式缓存⽅便,有成熟的⽅案。如果是单个应⽤或者对缓存访问要求很⾼的应⽤,⽤ EhCache 。如果是⼤型系统,存在缓存共享、分布式部署、缓存内容很⼤的,建议⽤ Redis。
- EhCache 也有缓存共享⽅案,不过是通过 RMI 或者 Jgroup 多播⽅式进⾏⼴播缓存通知更新,缓存共享复杂,维护不⽅便;简单的共享可以,但是涉及到缓存恢复,⼤数据缓存,则不合适。
整合步骤
1:导⼊Ehcache的坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
2:配置缓存技术实现使⽤Ehcache
yml
spring: cache: type: ehcache ehcache: config: classpath:ehcache.xml
resourcrs/ehcachexml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
<!--本地存储(可不需要) -->
<diskStore path="D:\ehcache" />
<!--默认缓存策略 -->
<!-- external:是否永久存在,设置为true则不会被清除,此时与timeout冲突,通常设置为false-->
<!-- diskPersistent:是否启用磁盘持久化-->
<!-- maxElementsInMemory:最大缓存数量-->
<!-- overflowToDisk:超过最大缓存数量是否持久化到磁盘-->
<!-- timeToIdleSeconds:最大不活动间隔,设置过长缓存容易溢出,设置过短无效果,可用于记录时效性数据,例如验证码-->
<!-- timeToLiveSeconds:最大存活时间-->
<!-- memoryStoreEvictionPolicy:缓存清除策略-->
<defaultCache
eternal="false"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU" />
<cache
name="codeMsg"
eternal="false"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="10"
timeToLiveSeconds="10"
memoryStoreEvictionPolicy="LRU" />
</ehcache>
注意前⾯的案例中,设置了数据保存的位置是codeMsg,这里我们也创建一个名为codeMsg的缓存空间,不然找不到会报错
3.创建controller
@RestController
@RequestMapping("/cache")
public class EhcacheController {
@Autowired
private EhcacheService ehcacheService;
/**
* 生成code
* @return
*/
@GetMapping
public String createCode(){
String code = ehcacheService.createCode("");
System.out.println(code);
return code;
}
@PostMapping
public String getCode(){
String code = ehcacheService.getCode("");
return code;
}
}
4.创建service
@Service
public class EhcacheService {
@CachePut(value = "codeMsg",key = "#code")//将生成的strCode放入key为code的缓存
public String createCode(String code) {
int max=10000;
int min=1000;
Random random=new Random();
String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
return strCode;
}
@Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
public String getCode(String code){
return null;
}
}
5.修改引导类
@SpringBootApplication
@EnableCaching//
public class DemoSpringbootEhcacheApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSpringbootEhcacheApplication.class, args);
}
}
总结
1. springboot使⽤Ehcache作为缓存实现需要导⼊Ehcache的坐标
2. 修改设置,配置缓存供应商为ehcache,并提供对应的缓存配置⽂件
6.4 SpringBoot整合Memcaced
memcache是⼀套分布式的⾼速缓存系统,⽬前被许多⽹站使⽤以提升⽹站的访问速度,尤其对于⼀些⼤型的、需要频繁访问数据库的⽹站访问速度提升效果⼗分显著。
springboot并没有⽀持使⽤memcached作为其缓存解决⽅案,也就是说在type属性中没有memcached的配置选项,这⾥就需要更变⼀下处理⽅式了。
memcached⽬前提供有三种客户端技术,分别是 Memcached Client for Java 、 SpyMemcached 和 Xmemcached ,其中性能指标各⽅⾯最好的客户端是Xmemcached,本次整合就使⽤这个作为客户端实现技术了。下⾯开始使⽤Xmemcached
1.导⼊xmemcached的坐标
<!-- https://mvnrepository.com/artifact/com.googlecode.xmemcached/xmemcached --> <dependency> <groupId>com.googlecode.xmemcached</groupId> <artifactId>xmemcached</artifactId> <version>2.4.7</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
2.配置memcached
application.yml
memcached: servers: localhost:11211 #memcached默认对外服务端⼝11211 poolSize: 10 opTimeout: 5000
3.配置实体类
@Component
@ConfigurationProperties(prefix = "memcached")
@Data
public class XmemcachedProperties {
private String servers;
private int poolSize;
private long opTimeout;
}
4.创建配置类获取memcached客户端对象
/**
* 该类返回⼀个客户端对象
*/
@Configuration
public class XmemcacheConfig {
@Autowired
private XmemcachedProperties xmemcachedProperties;
@Bean
public MemcachedClient getMemcachedClient(){
MemcachedClientBuilder builder = new XMemcachedClientBuilder(xmemcachedProperties.getServers());
builder.setConnectionPoolSize(xmemcachedProperties.getPoolSize());
builder.setOpTimeout(xmemcachedProperties.getOpTimeout());
MemcachedClient client = null;
try {
client = builder.build();
} catch (IOException e) {
e.printStackTrace();
}
return client;
}
}
5.使⽤xmemcached客户端操作缓存,注⼊MemcachedClient对象
@Service
public class XmemcacheService {
@Autowired
private MemcachedClient memcachedClient;
public String createCode(String code) {
int max=10000;
int min=1000;
Random random=new Random();
String strCode = String.valueOf(random.nextInt(max - min) + min + 1);
try {
memcachedClient.set("code",10,strCode);
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (MemcachedException e) {
e.printStackTrace();
}
return strCode;
}
@Cacheable(value = "codeMsg",key = "#code")//在缓存中取出key为code的值
public String getCode(String code){
String code1 = null;
try {
code1 = memcachedClient.get("code");
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (MemcachedException e) {
e.printStackTrace();
}
return code1;
}
}
6.controller
@RestController
@RequestMapping("/cache")
public class XmemcacheController {
@Autowired
private XmemcacheService xmemcacheService;
/**
* 生成code
* @return
*/
@GetMapping
public String createCode(){
String code = xmemcacheService.createCode("");
System.out.println(code);
return code;
}
@PostMapping
public String getCode(){
String code = xmemcacheService.getCode("");
return code;
}
}
7.引导类
@SpringBootApplication
@EnableCaching//
public class Demo9SpringbootMemcacheApplication {
public static void main(String[] args) {
SpringApplication.run(Demo9SpringbootMemcacheApplication.class, args);
}
}
总结
1. memcached安装后需要启动对应服务才可以对外提供缓存功能,安装memcached服务需要基于windows系统管理员权限
2. 由于springboot没有提供对memcached的缓存整合⽅案,需要采⽤⼿⼯编码的形式创建xmemcached客户端操作缓存
3. 导⼊xmemcached坐标后,创建memcached配置类,注册MemcachedClient对应的bean,⽤于操作缓存
4. 初始化MemcachedClient对象所需要使⽤的属性可以通过⾃定义配置属性类的形式加载