springboot-redis设置定时触发任务、删除定时任务

Redis实现定时触发任务、删除定时任务

业务背景

  • 个人平台账号可申请注销
  • 申请注销后七天内可撤销注销
  • 七天后触发删除账号业务的函数

需求梳理

  • 申请触发定时任务
  • 删除定时任务

配置

  • springboot-maven配置
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

springboot提供了spring-boot-starter-data-redis,里面也已经封装了spring中redis的配置spring-data-redis。
在这里插入图片描述

项目代码

http请求访问时,service层函数内部调用redisTemplate在Redis里设置一个注销key

代码例子如下:

  1. 个人平台账号可申请注销
    @Autowired
    private RedisTemplate redisTemplate;
    
    public void deleteUser(String key, String value){
   
        // 关键代码
        redisTemplate.opsForValue().set(key, value);
        // 设置七天注销时间
        redisTemplate.expire(key, DEFAULT_DELETE_TIME, TimeUnit.SECONDS);

        // 监听过期key,获取value使用
        String tempKey = key + "_2";
        redisTemplate.opsForValue().set(tempKey, value);
    }

注意: redis里面设置了两个key,原因在于:key过期之后,在ResdisExpirationListener 的 onMessage函数中 无法拿到key对应的value,所以设置两个,key不同但是value一样。这个value是为了key到期之后触发想要的任务函数。

  1. 申请注销后七天内可撤销注销
 public void withdrawDeleteUser(String key) {
        redisTemplate.delete(key);
        // 删除临时key
        redisTemplate.delete(key + "_2");
    }

注意: redis里面设置的两个key都必须删除

  1. 新建RedisListenerConfig.class
@Component
public class RedisListenerConfig {

    @Bean
    @Primary
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory){

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}
  1. 新建ResdisExpirationListener.class
    业务最主要在onMessage函数,key过期后会自动触发该函数,message信息是key,根据redisTemplate和另外设置的一个key拿到value,这个value在触发的定时任务函数里面用到了,所以必须拿到。
@Slf4j
@Component
@Transactional
    public class ResdisExpirationListener extends KeyExpirationEventMessageListener {


    @Autowired
    UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    public ResdisExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern){
        String messageKey = message.toString();

		// 业务实现
        if(messageKey.contains(RedisKey.DELETE_USER)){

            String userKey = redisTemplate.opsForValue().get(messageKey + "_2").toString();
            Long userId = Long.parseLong(userKey);
            // 触发定时任务
            userService.deleteUserProcess(userId);

            // 删除临时key
            redisTemplate.delete(messageKey + "_2");

        }
    }
}

好了,可以跑跑看了。

说明:

  • redis定时任务还可以有很多实现,文中只是一种。
  • 读者可以对redisTemplate中的方法进行封装,但因博主需求中只用到几个方法,出于代码可读性和解析性能考虑,不做封装。
  • 如果出现问题,要有耐心哦。可评论交流,也可自行查看api文档

sping_data_redis_api_document

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐