您的位置:首页 > 游戏 > 手游 > 中山企业网站多少钱_怎么制作动漫视频教程_电商运营是做什么的_百度网络推广

中山企业网站多少钱_怎么制作动漫视频教程_电商运营是做什么的_百度网络推广

2024/11/15 18:09:31 来源:https://blog.csdn.net/FBB360JAVA/article/details/143182433  浏览:    关键词:中山企业网站多少钱_怎么制作动漫视频教程_电商运营是做什么的_百度网络推广
中山企业网站多少钱_怎么制作动漫视频教程_电商运营是做什么的_百度网络推广

在这里插入图片描述

文章目录

  • 前言
  • 正文
    • 1、Lock4j的代码仓库
    • 2、pine-manage-common-redis的项目结构
    • 3、pine-manage-common-redis 的完整代码
      • 3.1 maven依赖:pom.xml
      • 3.2 redis连接参数:application.yaml
      • 3.3 RedisCache.java
      • 3.4 CacheConfig.java
      • 3.5 RedissonClientUtil.java
      • 3.6 SpringBeanUtil.java
      • 3.7 RedisLock.java
      • 3.8 RedisLockJsonKeyFunction.java
    • 4、pine-manage-common-redis的使用

前言

在平时使用SpringBoot框架时,有些业务场景会需要使用到Redis。但是,常见的Redis使用方式有好几种:

  • spring-boot-starter-data-redis:这是Spring Boot官方提供的Redis starter,它基于Spring Data Redis,提供了对Redis的集成支持。它默认使用Lettuce作为Redis客户端,但也支持Jedis客户端。通过这个starter,可以快速地在Spring Boot中整合、使用Redis,进行数据缓存、会话管理等操作。

  • spring-boot-starter-integration:这个starter提供了Spring Integration的支持,可以与Redis结合使用,实现分布式锁等功能。

  • spring-integration-redis:这是Spring Integration项目的一部分,提供了与Redis的集成支持,可以用于实现分布式锁等高级功能。

  • redisson-spring-boot-starter:Redisson是一个在Java环境下的Redis客户端,它提供了一系列的分布式数据结构和服务,如分布式锁、原子变量、集合等。这个starter简化了Redisson在Spring Boot中的配置和使用。

  • spring-boot-starter-data-redis-reactive:基于Webflux的响应式redis组件。

一般而言,我们会选择其中的一个。但是最近笔者发现了小黑鸟https://baomidou.com/resources/eco-system/ 的一个开源组件,就试着用了下。最后得到的结果是:真香!!!
在这里插入图片描述

这个Lock4j 本身是主要用于做分布式锁的。但是我们加入缓存组件,就能很容易得到一个具备缓存功能,同时支持分布式锁的一个小工具。

正文

1、Lock4j的代码仓库

https://gitee.com/baomidou/lock4j

Lock4j 本身支持集成多种Redis的连接器,我这次主要使用Redisson的集成。

我的集成项目实例仓库地址:https://gitee.com/fengsoshuai/pine-manage-system.git

进入pine-manage-system项目后,pine-manage-common-redis 模块是本文的重点。

注意:我的项目使用了java17版本,SpringBoot版本是3.3.4,如果想直接复用,需要自己调整。

2、pine-manage-common-redis的项目结构

在这里插入图片描述

  • com.pine.common.redis.cache :缓存包,实现了redis做缓存时的基本方法。
  • com.pine.common.redis.config:配置包,配置了缓存参数,redisson的相关配置,还有Spring获取Bean的工具类。
  • com.pine.common.redis.lock:redis做分布式锁的包装,实现了常用的工具方法。并自定义了redis key的拼接方法。

3、pine-manage-common-redis 的完整代码

3.1 maven依赖:pom.xml

<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><parent><groupId>com.pine</groupId><artifactId>pine-manage-common</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>pine-manage-common-redis</artifactId><packaging>jar</packaging><name>pine-manage-common-redis</name><url>http://maven.apache.org</url><properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><lock4j.version>2.2.7</lock4j.version><redisson.boot.version>3.25.2</redisson.boot.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- 使用lock4j实现分布式锁   https://gitee.com/baomidou/lock4j/--><dependency><groupId>com.baomidou</groupId><artifactId>lock4j-core</artifactId><version>${lock4j.version}</version></dependency><!-- 引入redisson--><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>${redisson.boot.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>lock4j-redisson-spring-boot-starter</artifactId><version>${lock4j.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId></dependency><!-- Spring Boot Starter Cache for integration --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency></dependencies>
</project>

3.2 redis连接参数:application.yaml

# redis配置 -使用时需要配置自己的redis
spring:data:redis:host: localhostport: 6379

3.3 RedisCache.java

package com.pine.common.redis.cache;import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;import java.util.Objects;/*** redis缓存** @author pine manage* @since 2024-08-13*/
@Slf4j
public class RedisCache {@Resource(name = "redissonCacheManager")private CacheManager redissonCacheManager;/*** 获取缓存** @param cacheName 缓存名称* @param key       缓存key* @return 缓存数据*/public Object get(String cacheName, String key) {log.info("RedisCache获取缓存,cacheName={}, key={}", cacheName, key);Cache cache = redissonCacheManager.getCache(cacheName);if (Objects.isNull(cache)) {return null;}// 从缓存中获取数据return cache.get(key);}/*** 设置缓存** @param cacheName 缓存名称* @param key       缓存key* @param value     缓存数据*/public void set(String cacheName, String key, Object value) {log.info("RedisCache设置缓存,cacheName={}, key={}, value={}", cacheName, key, value);Cache cache = redissonCacheManager.getCache(cacheName);if (Objects.isNull(cache)) {return;}// 将数据放入缓存cache.put(key, value);}/*** 移除缓存** @param cacheName 缓存名称* @param key       缓存key*/public void remove(String cacheName, String key) {log.info("RedisCache移除缓存,cacheName={}, key={}", cacheName, key);Cache cache = redissonCacheManager.getCache(cacheName);if (Objects.isNull(cache)) {return;}// 从缓存中移除数据cache.evict(key);}/*** 移除所有缓存** @param cacheName 缓存名称*/public void removeAll(String cacheName) {log.info("RedisCache移除所有缓存,cacheName={}", cacheName);Cache cache = redissonCacheManager.getCache(cacheName);if (Objects.isNull(cache)) {return;}// 从缓存中移除数据cache.clear();}
}

3.4 CacheConfig.java

package com.pine.common.redis.config;import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.pine.common.redis.cache.RedisCache;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.spring.cache.RedissonSpringCacheManager;
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 缓存配置** @author pine manage* @since 2024-08-13*/
@Configuration
public class CacheConfig {@Bean(name = "redissonCacheManager")@ConditionalOnMissingBeanpublic CacheManager redissonCacheManager(@Autowired RedissonClient redissonClient) {// 可以自定义缓存配置return new RedissonSpringCacheManager(redissonClient);}@Bean@ConditionalOnMissingBeanpublic RedisCache redisCache() {return new RedisCache();}@Beanpublic RedissonAutoConfigurationCustomizer redissonAutoConfigurationCustomizer() {// 增加支持序列化java8的时间ObjectMapper objectMapper = new ObjectMapper();objectMapper.registerModule(new JavaTimeModule());JsonJacksonCodec jsonJacksonCodec = new JsonJacksonCodec(objectMapper);return config -> config.setCodec(jsonJacksonCodec);}
}

3.5 RedissonClientUtil.java

package com.pine.common.redis.config;import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;import java.time.Duration;/*** redissonClient 工具类** @author pine manage* @since 2024-08-22*/
public class RedissonClientUtil {private static RedissonClient redissonClient;public static RedissonClient getRedissonClient() {init();return redissonClient;}/*** 设置缓存** @param key               key* @param value             value* @param timeToLiveSeconds 失效时间(单位:秒)*/public static void setCacheWithExpiration(String key, Object value, long timeToLiveSeconds) {init();RBucket<Object> bucket = redissonClient.getBucket(key);// 设置缓存值和过期时间bucket.set(value, Duration.ofSeconds(timeToLiveSeconds));}/*** 设置缓存** @param key   key* @param value value*/public static void setCache(String key, Object value) {init();RBucket<Object> bucket = redissonClient.getBucket(key);// 设置缓存值bucket.set(value);}/*** 获取缓存** @param key key* @return value*/public static Object getCache(String key) {init();RBucket<Object> bucket = redissonClient.getBucket(key);return bucket.get();}/*** 移除缓存** @param key key*/public static void removeCache(String key) {init();redissonClient.getBucket(key).delete();}private static void init() {if (redissonClient == null) {redissonClient = SpringBeanUtil.getByClass(RedissonClient.class);}}
}

3.6 SpringBeanUtil.java

package com.pine.common.redis.config;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;/*** springbean工具类** @author pine manage* @since 2024-08-09*/
@Component
public class SpringBeanUtil implements BeanFactoryAware {private static BeanFactory beanFactory;@Overridepublic void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {SpringBeanUtil.beanFactory = beanFactory;}public static <T> T getByClass(Class<T> clazz) {return beanFactory.getBean(clazz);}
}

3.7 RedisLock.java

package com.pine.common.redis.lock;import com.baomidou.lock.LockInfo;
import com.baomidou.lock.LockTemplate;
import com.pine.common.redis.config.SpringBeanUtil;import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.function.Function;/*** redis锁** @author pine manage* @since 2024-08-09*/
public class RedisLock {private static LockTemplate lockTemplate;/*** 获取锁超时时间*/private static final Long LIMIT_STREAM_ACQUIRE_TIMEOUT = 0L;private static final Long ACQUIRE_TIMEOUT = 3000L;/*** 锁过期时间*/private static final Long EXPIRE = 5000L;/*** redis分布式锁(redisson自动续锁)** @param bizRunnable 业务逻辑* @param key         锁key*/public static void lock(Runnable bizRunnable, String key, Long acquireTimeout) {initLockTemplate();// 获取锁超时时间,默认3秒acquireTimeout = Optional.ofNullable(acquireTimeout).orElse(ACQUIRE_TIMEOUT);// expire锁过期时间为-1:不过期,redisson 自动续锁LockInfo lockInfo = lockTemplate.lock(key, -1L, acquireTimeout);if (lockInfo == null) {throw new RuntimeException("获取锁失败");}try {bizRunnable.run();lockTemplate.releaseLock(lockInfo);} catch (Exception e) {lockTemplate.releaseLock(lockInfo);throw e;}}/*** redis分布式锁(redisson自动续锁)** @param bizCallable 业务逻辑* @param key         锁key*/public static <Result> Result lock(Callable<Result> bizCallable, String key, Long acquireTimeout) throws Exception {initLockTemplate();// 获取锁超时时间,默认3秒acquireTimeout = Optional.ofNullable(acquireTimeout).orElse(ACQUIRE_TIMEOUT);// expire锁过期时间为-1:不过期,redisson 自动续锁LockInfo lockInfo = lockTemplate.lock(key, -1L, acquireTimeout);if (lockInfo == null) {throw new RuntimeException("获取锁失败");}try {Result result = bizCallable.call();lockTemplate.releaseLock(lockInfo);return result;} catch (Exception e) {lockTemplate.releaseLock(lockInfo);throw e;}}/*** 加锁限流<br>* <b>此处注意:上锁后不手动解锁,等待过期时间自动解锁</b>** @param param 锁参数*/public static void lockAndLimitStream(Object param) {lockAndLimitStream(param, null, null, new RedisLockJsonKeyFunction());}/*** 加锁限流<br>* <b>此处注意:上锁后不手动解锁,等待过期时间自动解锁</b>** @param expire         锁过期时间* @param acquireTimeout 获取锁超时时间*/public static void lockAndLimitStream(Object param, Long expire, Long acquireTimeout) {lockAndLimitStream(param, expire, acquireTimeout, new RedisLockJsonKeyFunction());}/*** 加锁限流<br>* <b>此处注意:上锁后不手动解锁,等待过期时间自动解锁</b>** @param expire         锁过期时间* @param acquireTimeout 获取锁超时时间* @param keyFunction    计算锁key的函数*/public static void lockAndLimitStream(Object param, Long expire, Long acquireTimeout, Function<Object, String> keyFunction) {initLockTemplate();// 锁过期时间默认5秒expire = Optional.ofNullable(expire).orElse(EXPIRE);// 获取锁超时时间默认0秒acquireTimeout = Optional.ofNullable(acquireTimeout).orElse(LIMIT_STREAM_ACQUIRE_TIMEOUT);// 计算锁keyString key = keyFunction.apply(param);// 尝试获取锁LockInfo lockInfo = lockTemplate.lock(key, expire, acquireTimeout);// 获取锁失败if (lockInfo == null) {throw new RuntimeException("调用过于频繁,业务处理中,请稍后再试");}}/*** 初始化lockTemplate*/private static void initLockTemplate() {if (lockTemplate == null) {lockTemplate = SpringBeanUtil.getByClass(LockTemplate.class);}Objects.requireNonNull(lockTemplate, "lockTemplate is null");}
}

3.8 RedisLockJsonKeyFunction.java

package com.pine.common.redis.lock;import com.fasterxml.jackson.databind.ObjectMapper;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;/*** redis锁key生成函数** @author pine manage* @since 2024-08-09*/
public class RedisLockJsonKeyFunction implements Function<Object, String> {private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();private static final Lock LOCK = new ReentrantLock();/*** Applies this function to the given argument.** @param object the function argument* @return the function result*/@Overridepublic String apply(Object object) {return serializeToJson(object);}/*** 序列化对象为json** @param object 对象* @return json*/private static String serializeToJson(Object object) {try {LOCK.lock();return OBJECT_MAPPER.writeValueAsString(object);} catch (Exception e) {throw new RuntimeException(e);} finally {LOCK.unlock();}}
}

4、pine-manage-common-redis的使用

在要使用的模块中,引入如下依赖:

        <dependency><groupId>com.pine</groupId><artifactId>pine-manage-common-redis</artifactId><version>${pine-manage-common-redis.version}</version></dependency>

随后直接使用RedisLock的静态方法即可,比如:

// 限流
RedisLock.lockAndLimitStream(triggerContext, expire, acquireTimeout);

而如果要使用缓存功能,则直接注入 RedisCache,然后使用即可,比如:

@Resource
protected RedisCache redisCache;// 设置缓存
redisCache.set(CacheNameConstant.SYS_CONFIG_CACHE_NAME, sysConfig.getConfigKey(), newSysConfigBo);

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com