抄袭了这位博主的代码,运行时好用,就重新记录了一下
链接: Spring Boot实现Redis同数据源动态切换DB | Spring Cloud 31
链接: Spring Boot实现Redis同数据源动态切换DB | Spring Cloud 31
代码如下(示例):
package com.ruoyi.common.redis;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;
@Slf4j
@Aspect
@Component
public class RedisIndexSelectAspect {
@Value("${spring.redis.database:0}")
private int defaultIndex;
/**
* 创建RedisSelect对应的切面,来对标有注解的方法拦截
*
* @param point
* @return
* @throws Throwable
*/
@Around("@annotation( com.ruoyi.common.redis.RedisSelect)")
@ConditionalOnBean(RedisSelectTemplate.class)
public Object configRedis(ProceedingJoinPoint point) throws Throwable {
int index = defaultIndex;
try {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
RedisSelect config = method.getAnnotation(RedisSelect.class);
if (config != null) {
index = config.index();
}
RedisSelectSupport.selectIndex(index);
return point.proceed();
} finally {
RedisSelectSupport.selectIndex(defaultIndex);
log.debug("redis index reset {} to {}", index, defaultIndex);
}
}
}
代码如下(示例):
package com.ruoyi.common.redis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Slf4j
@Configuration(proxyBeanMethods = false)
public class RedisIndexSelectConfig {
@Autowired(required = false)
private LettuceConnectionFactory factory;
@Bean
@ConditionalOnMissingBean
public RedisSelectTemplate<String, Object> redisIndexSelectTemplate() {
/**
* 使用默认注入的RedisConnectionFactory factory时,切换db时出现以下异常:
*
* java.lang.UnsupportedOperationException:Selecting a new database not supported due to shared connection.
* Use separate ConnectionFactorys to work with multiple databases
* 从默认RedisConnectionFactory factory注入,改为LettuceConnectionFactory factory,
* 并通过factory.setShareNativeConnection(false)关闭共享链接
*/
RedisSelectTemplate<String, Object> redisTemplate = new RedisSelectTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericToStringSerializer(Object.class));
redisTemplate.setValueSerializer(new StringRedisSerializer());
// 关闭共享链接
factory.setShareNativeConnection(false);
redisTemplate.setConnectionFactory(factory);
redisTemplate.afterPropertiesSet();
log.info("实例化 SelectableRedisTemplate 对象完成");
return redisTemplate;
}
}
代码如下(示例):
package com.ruoyi.common.redis;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.*;
/**
* 注解,用于切换同一redis数据源下的不同db index
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedisSelect {
/**
* redis库 0 - 15 库
*
* @return
*/
int index() default 0;
}
代码如下(示例):
package com.ruoyi.common.redis;
/**
* Redis 切换DB操作
*/
public class RedisSelectSupport {
/**
* 定义一个静态变量,用于线程间传递值
*/
private static final ThreadLocal<Integer> DB_SELECT_CONTEXT = new ThreadLocal<>();
public static void selectIndex(int db) {
DB_SELECT_CONTEXT.set(db);
}
public static Integer getSelectIndex() {
return DB_SELECT_CONTEXT.get();
}
}
代码如下(示例):
package com.ruoyi.common.redis;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
public class RedisSelectTemplate<K, V> extends RedisTemplate<K, V> {
@Override
protected RedisConnection createRedisConnectionProxy(RedisConnection pm) {
return super.createRedisConnectionProxy(pm);
}
/**
* 在连接Redis之前做一些配置
*
* @param connection
* @param existingConnection
* @return
*/
@Override
protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
Integer index = RedisSelectSupport.getSelectIndex();
if (index != null) {
//切换 redis db 到 其他的库
connection.select(index);
}
return super.preProcessConnection(connection, existingConnection);
}
}
代码如下(示例):
package com.ruoyi.system.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.redis.RedisSelectSupport;
import com.ruoyi.common.redis.RedisSelectTemplate;
import com.ruoyi.system.service.IRedisDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
/**
* 参数配置 服务层实现
*
* @author ruoyi
*/
@Service
public class RedisDataServiceImpl implements IRedisDataService
{
@Autowired
private RedisSelectTemplate<String, Object> redisSelectTemplate;
@Override
public void selectRedisData(){
JSONObject jsonObject = new JSONObject();
// 获取当前时间的毫秒数
long currentMillis = System.currentTimeMillis();
// 将毫秒数转换为日期对象
Date date = new Date(currentMillis);
// 定义日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 使用日期格式将日期对象转换为字符串
String dateString = sdf.format(date);
jsonObject.put("aaTitle","aaTitle"+dateString);
jsonObject.put("aaName","aaName"+dateString);
jsonObject.put("aaContent","aaContent"+dateString);
RedisSelectSupport.selectIndex(3);//此处切换到db3库
// 切换DB数据库
RedisSelectSupport.selectIndex(4);//此处切换到db3库
redisSelectTemplate.opsForList().leftPushAll("WAHAHA:WAHAHA1:WAHAHA2", jsonObject.toString());
}
}