设置database 不生效剖析
- 前言
- 配置
- 加载类
- 问题
- commons-pool 对象池
- 对比
主页传送门: 传送
前言
事情是这样的 今天在拉取了同事的代码做redis缓存设置的时候,发现即使已经设置了database, 但是存数据的时候还是用的默认0数据库。这引起了我的好奇,遂开始琢磨是什么情况造成的这种现象。
配置
上述仅为测试代码问题,为了便于维护可以这么写,
spring:redis:host: ${REDIS_HOST:localhost}port: ${REDIS_PORT:6379}password: ${REDIS_PASSWORD:}database: ${REDIS_DATABASE:0}
加载类
然后通过RedisConfiguration 加载
@ConfigurationProperties("spring.redis")public class RedisConfiguration {private String host;private int port;private String password;private int database;// getters and setters...}
问题
上网找了一系列的文章都没解决,后来仔细观察研究发现是database多了个空格,正确的该是这样,没想到一个空格浪费了这么多时间
信心满满的以为这就万事大吉了,结果一运行发现依然不可以,后又开始检查,最后发现是少了几个依赖
发现没有引入commons-pool2依赖,加上了依赖之后再运行发现已经切换了
也可以引入lettuce-core 依赖
<!-- lettuce-core --><dependency><groupId>io.lettuce.core</groupId><artifactId>lettuce-core</artifactId></dependency>
commons-pool 对象池
引入Commons Pool对象池,用于缓存Redis连接的原因是因为Lettuce本身是基于Netty的异步驱动,在异步访问时并不需要创建连接池,但基于Servlet模型的同步访问时,连接池是有必要的。目的是为了复用对象,以减少创建对象的开销,所以一定记得要加这个依赖。
/*** Creates an instance that can be served by the pool and wrap it in a* {@link PooledObject} to be managed by the pool.** @return a {@code PooledObject} wrapping an instance that can be served by the pool** @throws Exception if there is a problem creating a new instance,*this will be propagated to the code requesting an object.*/PooledObject makeObject()throws Exception;/*** Destroys an instance no longer needed by the pool.* * It is important for implementations of this method to be aware that there* is no guarantee about what state obj
will be in and the* implementation should be prepared to handle unexpected errors.*
* * Also, an implementation must take in to consideration that instances lost* to the garbage collector may never be destroyed.*
** @param p a {@code PooledObject} wrapping the instance to be destroyed** @throws Exception should be avoided as it may be swallowed by*the pool implementation.** @see #validateObject* @see ObjectPool#invalidateObject*/void destroyObject(PooledObject p)throws Exception;/*** Ensures that the instance is safe to be returned by the pool.** @param p a {@code PooledObject} wrapping the instance to be validated** @return false
if obj
is not valid and should*be dropped from the pool, true
otherwise.*/boolean validateObject(PooledObject p);/*** Reinitializes an instance to be returned by the pool.** @param p a {@code PooledObject} wrapping the instance to be activated** @throws Exception if there is a problem activating obj
,*this exception may be swallowed by the pool.** @see #destroyObject*/void activateObject(PooledObject p)throws Exception;/*** Uninitializes an instance to be returned to the idle object pool.** @param p a {@code PooledObject} wrapping the instance to be passivated** @throws Exception if there is a problem passivating obj
,*this exception may be swallowed by the pool.** @see #destroyObject*/void passivateObject(PooledObject p)throws Exception;
注意:
Jedis 和Lettuce 是Java 操作Redis 的客户端。
在Spring Boot 1.x 版本默认使用的是Jedis ,而在Spring Boot 2.x 版本默认使用的就是Lettuce。
所以如果你用的是1.x版本的话 需要把 RedisConnectionFactory factory 替换为LettuceConnectionFactory lettuceConnectionFactory
同时在依赖中排除lettuce的jar 改为用jedis
对比
commons-pool2
和 lettuce-core
都是在处理 Redis 连接池方面常用的依赖,但它们有不同的设计和适用场景,因此在选择使用哪个依赖时需要根据具体情况进行权衡。
commons-pool2
是 Apache Commons 项目中的一个组件,用于实现通用的对象池。它不仅仅适用于 Redis 连接池,还可以用于其他对象的池化管理。commons-pool2
的设计比较通用,允许你管理任意类型的对象池,因此可以更灵活地适应不同的场景。如果你的项目需要管理多个类型的对象池,或者你希望在 Redis 之外使用对象池功能,那么选择 commons-pool2
是一个不错的选择。
另一方面,lettuce-core
是一个专门为 Redis 设计的客户端库。它提供了丰富的功能和性能优化,专注于提供高效的 Redis 连接和操作。lettuce-core
自带了连接池的功能,你可以使用它内置的连接池来管理 Redis 连接,无需额外的依赖。
所以,选择使用 commons-pool2
还是 lettuce-core
取决于你的项目需求:
- 如果你只需要管理 Redis 连接池,而不需要通用的对象池功能,那么使用
lettuce-core
内置的连接池可能更为方便和简洁。 - 如果你的项目需要管理多个类型的对象池,或者需要在其他场景中使用对象池,那么
commons-pool2
提供的通用对象池功能可能更适合。
如果喜欢的话,欢迎 关注 点赞 评论 收藏一起讨论你的支持就是我✍️创作的动力!