SpringBoot自定义RedisConig时RedisConnectionFactory显示Could not autowire. No beans of 'RedisConnectionFactory' type found.问题。
使用时如下引用:
@Autowired
private RedisTemplate<String, PatientVo> redisTemplate;
//操作
redisTemplate.opsForList().rightPush(roomCode, vo); //redisTemplate null
redisTemplate一直报null
断点追踪,发现飘红的地方,正常入注了,与飘红无关。报空似乎是@Autowired入注方式没成功。修改为如下成功。
private final RedisTemplate<String, PatientVo> redisTemplate;
@Autowired
public RedisQueueUtil(@Qualifier("patientVoRedisTemplate") RedisTemplate<String, PatientVo> redisTemplate) {
this.redisTemplate = redisTemplate;
}
把排队完整代码记录如下:
SpringBoot配置文件中Redis的配置略。
1、先定义一个VO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PatientVo implements Serializable {
private String patientName;
private String patientCardNo;
private Integer queueNum;
private String windowNo;
private String ampm;
}
2、自定义Redis配置文件
@Configuration
@Slf4j
public class JhRedisConfig {
/**
* 创建并配置一个专门用于存储和操作PatientVo对象的RedisTemplate bean。
*
* @param factory RedisConnectionFactory对象,用于创建与Redis服务器的连接。
* @return 配置好的RedisTemplate对象,可用于操作Redis中的PatientVo数据。
*/
@Bean(name = "patientVoRedisTemplate")
public RedisTemplate<String, PatientVo> patientVoRedisTemplate(RedisConnectionFactory factory) {
log.info("Redis配置文件中bean已经加载!");
RedisTemplate<String, PatientVo> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用StringRedisSerializer对键进行序列化,保证键的一致性
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
// 使用Jackson2JsonRedisSerializer对值进行序列化,支持复杂的对象存储
Jackson2JsonRedisSerializer<PatientVo> redisSerializer = new Jackson2JsonRedisSerializer<>(PatientVo.class);
// 配置ObjectMapper以处理null值的序列化,提高与PatientVo对象的兼容性
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure( SerializationFeature.FAIL_ON_EMPTY_BEANS, false );
objectMapper.setSerializationInclusion( JsonInclude.Include.NON_NULL ); // 包含非null值
redisSerializer.setObjectMapper(objectMapper);
template.setValueSerializer(redisSerializer);
template.setHashValueSerializer(redisSerializer);
try {
template.afterPropertiesSet(); // 初始化RedisTemplate
} catch (Exception e) {
log.error("初始化RedisTemplate失败: ", e);
// 根据实际情况处理异常,例如回滚操作或其他恢复措施
}
return template;
}
}
3、写一个Redis工具类:
@Slf4j
@Service
public class RedisQueueUtil {
private final RedisTemplate<String, PatientVo> redisTemplate;
@Autowired
public RedisQueueUtil(@Qualifier("patientVoRedisTemplate") RedisTemplate<String, PatientVo> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 将患者信息添加到指定房间号的队列中。
* 该操作将在Redis中对应的房间号列表的末尾添加一个患者对象。
*
* @param roomCode 房间号,作为Redis列表的键。
* @param vo 患者信息对象,将被添加到列表中。
*/
public void addPatient2Queue(String roomCode, PatientVo vo) {
// 使用Redis List的rightPush方法,将患者对象添加到指定房间号的队列末尾
redisTemplate.opsForList().rightPush(roomCode, vo);
}
/**
* 队长度
* @param roomCode 诊室编码
* @return Long长度
*/
public Long getQueueLength(String roomCode) {
return redisTemplate.opsForList().size(roomCode);
}
// 获取队列数据
public List<PatientVo> getQueueData(String roomCode) {
return redisTemplate.opsForList().range(roomCode, 0, -1);
}
// 某人中途离开队伍
public void leaveQueue(String roomCode, PatientVo patientVo) {
redisTemplate.opsForList().remove(roomCode, 0, patientVo);
}
// 队首离队
public PatientVo headLeaveQueue(String roomCode) {
PatientVo leftPop = redisTemplate.opsForList().leftPop(roomCode);
return leftPop;
}
// 得到某人队列中的位置
public List<Integer> getOnesPosition(String roomCode, PatientVo patientVo) {
List<PatientVo> queueData = getQueueData(roomCode);
int myPositionBeforeNum = queueData.indexOf(patientVo);
int myPosition = myPositionBeforeNum + 1;
int size = queueData.size();
// 当前排队res[0]人,您排在第res[1]位,前面还有res[2]位。
List<Integer> result = new ArrayList<>();
result.add(size);
result.add(myPosition);
result.add(myPositionBeforeNum);
return result;
}
// 插队操作
public void jumpAQueue(String roomCode, PatientVo jumpChecker, PatientVo targetChecker, Integer jumpType) {
// 在target前面插队
if (jumpType.equals(1)) {
redisTemplate.opsForList().leftPush(roomCode, targetChecker, jumpChecker);
}
if (jumpType.equals(2)) {
redisTemplate.opsForList().rightPush(roomCode, targetChecker, jumpChecker);
}
}
}