【SpringBoot2.x实战】整合redis及常用功能

star2017 1年前 ⋅ 1283 阅读

一般的项目中都会使用缓存,如果你的项目是集群的,那么你肯定会使用redis来做缓存。
今天给大家讲讲SpringBoot如何整合redis,以及一些常用的用法。示例有:@Cacheable、@CacheEvict、保存、查询、删除、消息订阅发布、id自增、分布式锁、lua脚本、哨兵、redis cluster集群。

整体结构

imagepng

pom配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.cimu</groupId>
	<artifactId>redis</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>redis</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<pool>2.4.2</pool>
        <fastjson-version>1.2.47</fastjson-version>
	</properties>

	<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
		<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-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.16.20</version>
			<scope>compile</scope>
		</dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>


核心代码

RedisConfig类:配置了key生成策略,缓存管理器,不同泛型的redisTemplate,配置不同的RedisConnectionFactory。列出部分代码,具体源码可以看文末源码地址。


/**
 * Redis缓存配置类
 */
@Configuration
@EnableRedisRepositories
public class RedisConfig extends CachingConfigurerSupport {
    @Autowired
    private RedisConnectionFactory factory;
    /**
     * 自定义缓存key生成策略
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(target.getClass().getName()).append("_");
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append("_").append(obj == null ? "" : obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * 缓存管理器
     */
    @Bean
    @Primary
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 设置缓存有效期一小时
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1));
        return RedisCacheManager
                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
                .cacheDefaults(redisCacheConfiguration).build();
    }

    /**
     * 5分钟失效缓存管理器
     */
    @Bean
    public CacheManager fiveMinutesManager(RedisConnectionFactory factory) {
        // 设置缓存有效期5分钟
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(5));
        return RedisCacheManager
                .builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
                .cacheDefaults(redisCacheConfiguration).build();
    }

    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Serializable, Serializable> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<Serializable, Serializable> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        //设置序列化工具
        setSerializer(template);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    @ConditionalOnMissingBean(StringRedisTemplate.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(factory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setValueSerializer(stringRedisSerializer);
        template.setKeySerializer(stringRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 设置序列化工具
     * @param template RedisTemplate
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    private void setSerializer(RedisTemplate template) {
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        template.setDefaultSerializer(jackson2JsonRedisSerializer);//发布订阅的时候,传输对象如果使用@Builder注解,需要实现无参构造函数
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
    }

}

RedisSubListenerConfig类:配置了发布订阅的相对于的类,监听的通道。

@Configuration
public class RedisSubListenerConfig {
    @Autowired
  RedisPublisher redisPublisher;

  /**
 * 初始化监听器 */  @Bean
  RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
  MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
  container.setConnectionFactory(connectionFactory);
  container.addMessageListener(listenerAdapter, new ChannelTopic(redisPublisher.getChannel()));
 return container;
  }

    /**
 * 利用反射来创建监听到消息之后的执行方法 */  @Bean
  MessageListenerAdapter listenerAdapter(RedisReceiver redisReceiver) {
        return new MessageListenerAdapter(redisReceiver, "receiveMessage");
  }

}

发布/订阅处理的业务类:
imagepng
如图,包里面是发布/订阅的代码
RedisPublisher:为发布消息逻辑。
RedisReceiver:为接收消息,在这里可以实现你的业务代码。
MessageHandler:为接口,业务处理的类都要实现该接口。messageType方法表示支持哪些业务,processMsg方法为具体的处理方法。不同的业务消息,只要你的消息类中定义了业务类型,并传入相应的业务类型,在RedisReceiver中判断支持哪些业务,在获取相应业务的处理类进行处理,具体实现可以看源码。

UserServiceTest为单元测试类,所有的测试代码都在这里。

ClusterConfigProperties类为redis cluster的节点配置。

配置

application.properties文件:

#spring.redis.host=127.0.0.1
#spring.redis.database=0
#spring.redis.port=6379
#spring.redis.password=

spring.cache.type=redis
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.min-idle=0
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=10000
#spring.redis.sentinel.master=mymaster
#spring.redis.sentinel.nodes=127.0.0.1:5000,127.0.0.1:5001,127.0.0.1:5002
redis.cluster.nodes=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381
redis.cluster.maxRedirects=3

脚本

lua.script目录下是lua脚本,lua的语法可以去官网看看。

源码地址

本文为博主原创文章,未经博主允许不得转载。
更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: