Springboot系列-整合Redis
前言:缓存在项目的开发中其中至关重要的作用,比如通过缓存可以减少服务器数据库的压力,本篇博客将主要对于redis整合进行介绍,如果大家对redis还不是特别了解的,请访问博客的另一篇博客:Redis详解及使用
使用Java操作Redis的方案有很多,Jedis、Spring Data Redis、Spring Cache等,我们将依次进行介绍
1.Spring Data Redis
1.创建工程,引入Redis
2.创建成功后,还需要引入 commos-pool2 和 web 的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
3.在application.properties里面配置Redis信息和连接池的信息
spring.redis.database=0
spring.redis.password=123456
spring.redis.port=6379
spring.redis.host=192.168.181.1
spring.redis.lettuce.pool.min-idle=5
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=1ms
spring.redis.lettuce.shutdown-timeout=100ms
4.自动配置
项目中引入了 Spring Data Redis ,并配置了 Redis 的基本信息,此时,自动化配置就会自动生效,查看源码如下:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
从源码中可以看出该配置在 RedisOperations 存在的情况下才会生效(即项目中引入了 Spring Data Redis),然后导入在 application.properties 中配置的属性和连接池信息;最后,提供了两个 Bean ,RedisTemplate 和 StringRedisTemplate , StringRedisTemplate 是 RedisTemplate 的子类,两个的方法基本一致,主要体现在操作的数据类型不同,RedisTemplate 中的两个泛型都是 Object ,所以存储的 key 和 value 都可以是一个对象,而 StringRedisTemplate 的 两个泛型都是 String ,意味者 StringRedisTemplate 的 key 和 value 都只能是字符串,如果开发者不自己配置,默认以上配置生效
5.基本使用
新建service,在service中注入StringRedisTemplate 或 RedisTemplate,如下:
@Service
public class DemoService {
@Autowired
RedisTemplate redisTemplate;
public void redis(){
//RedisTemplate 中,key 默认的序列化方案是 JdkSerializationRedisSerializer,使用 StringRedisTemplate可避免key带有前缀
redisTemplate.setKeySerializer(new StringRedisSerializer());
ValueOperations ops = redisTemplate.opsForValue();
ops.set("key","redis");
Object o = ops.get("key");
System.out.println(o);
}
}
Redis 中的数据操作,可以分为两种,一种是针对 key 的操作,相关的方法就在 RedisTemplate 中,另一种是针对具体数据类型的操作,相关的方法需要首先获取对应的数据类型,获取相应数据类型的操作方法是 opsForXXX;调用该方法就可以将数据存储到 Redis 中
也可以直接使用 StringRedisTemplate:
@Autowired
StringRedisTemplate stringRedisTemplate;
public void redis(){
ValueOperations ops = stringRedisTemplate.opsForValue();
ops.set("key","redis");
Object o = ops.get("key");
System.out.println(o);
}
2.Spring Cache
在上述的Spring Boot中整合Redis中,开发者只需要引入Spring Data Redis依赖,然后配置redis的基本信息,系统就会提供一个RedisTemplate供开发者使用;接下来讲的是结合Cache的用法在Spring Boot中,使用Redis来作为Cache的实现,进而实现数据的缓存
1.pom.xml配置
和上面新建工程原理一样,区别是去除commons 依赖后引入一个 cache 依赖,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2.在application.properties配置文件中配置cache如下:
spring.cache.cache-names=wxy(缓存名)
spring.redis.port=6379
spring.redis.host=192.168.131.1
3.修改启动类,添加@EnableCaching,表示开启缓存,如下:
@SpringBootApplication
@EnableCaching
public class DataredisApplication {
public static void main(String[] args) {
SpringApplication.run(DataredisApplication.class, args);
}
}
4.完成如上配置后,Spring Boot会自动在后台配置一个RedisCacheManager,源码如下:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisConnectionFactory.class)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnMissingBean(CacheManager.class)
@Conditional(CacheCondition.class)
class RedisCacheConfiguration {
@Bean
RedisCacheManager cacheManager(CacheProperties cacheProperties, CacheManagerCustomizers cacheManagerCustomizers,
ObjectProvider<org.springframework.data.redis.cache.RedisCacheConfiguration> redisCacheConfiguration,
ObjectProvider<RedisCacheManagerBuilderCustomizer> redisCacheManagerBuilderCustomizers,
RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(
determineConfiguration(cacheProperties, redisCacheConfiguration, resourceLoader.getClassLoader()));
List<String> cacheNames = cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
}
redisCacheManagerBuilderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return cacheManagerCustomizers.customize(builder.build());
}
}
根据如上源码可以看出系统会自动提供一个RedisCacheManager的Bean,这个RedisCacheManager间接实现了Spring中的Cache接口,有了这个Bean,就可以直接使用Spring中的缓存注解和接口,而缓存数据则会被自动存储到Redis上
5.缓存使用
@CacheConfig:用来描述该类中所有方法使用的缓存名称,当然也可以不使用该注解,直接在具体的缓存注解上配置名称,如下:
@Service
@CacheConfig(cacheNames = "wxy")
public class UserService {
}
@Cacheable:一般加在查询方法上,表示将一个方法的返回值缓存起来,默认情况下,缓存的key就是方法的参数,缓存的value就是方法的返回值,如下:
@Cacheable(key = "#id")
public User getUserById(Integer id) {
System.out.println("getUserById");
return userMapper.getUserById(id);
}
@CachePut:一般加在更新方法上,数据库数据更新后,缓存中的数据也要更新,使用该注解,可以将方法的返回值自动更新到已经存在的key上,代码如下:
@CachePut(key = "#user.id")
public User updateUserById(User user) {
return user;
}
@CacheEvict:一般加在删除方法上,数据库数据删除后,相关的缓存数据也要自动清除,该注解在使用的时候也可以配置按照某种条件删除或者配置清除所有缓存,示例代码如下:
@CacheEvict()
public void deleteUserById(Integer id) {
//从数据库中删除数据
}
3.Jedis
最后讲到关于Jedis操作,其实相对于以上两种,Jedis相对用的少一些,所以在此做出简单的介绍,可以用 JAVA SE工程来测试
1.新建一个普通的maven项目即可,然后添加依赖如下:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2.创建一个类,测试程序是否连接成功,如下:
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.131.1", 6379);
String ping = jedis.ping();
System.out.println(ping);
}
3.控制台输出如下表示成功
4.Jedis类中方法名称和redis中的命令基本是一致的,我们可以通过Jedis创建一个连接池,如下:
public static void main(String[] args) {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
//连接池的最大数据库连接数,0表示无限制
config.setMaxTotal(100);
//最大空闲数,数据库连接的最大空闲时间,超过空闲时间,数据库连接将被标记为不可用,然后被释放,设为0表示无限制
config.setMaxIdle(20);
JedisPool jedisPool = new JedisPool(config, "192.168.131.1", 6379);
Jedis jedis = jedisPool.getResource();
System.out.println(jedis.ping());
}
以上创建完连接池之后就不会频繁创建和销毁连接了,在JavaSE环境中可以把连接池配置成一个单例模式,如果用了Spring容器的话,可通过Spring容器管理…
结语:【end】