【发布时间】:2016-06-15 18:31:50
【问题描述】:
我正在通过 Jetty/CometD 运行一个长时间运行的 Web 服务,并且我正在使用 Redisson 库来连接到 redis。我正在使用单例模式来获取我的 RedissonClient/连接,但我不确定这是否是最好的方法。
类看起来像这样:
public class RedisClient {
// singleton instance of our RedisonClient/connection
private static RedissonClient _redissonInstance;
public static String REDIS_HOST = "my.redishost.com:6379";
private static RedissonClient setupRedis() {
org.redisson.Config config = new org.redisson.Config();
config.useSingleServer()
.setAddress(REDIS_HOST)
.setConnectionPoolSize(200);
return Redisson.create(config);
}
public static RedissonClient getRedis() {
if (_redissonInstance == null) {
_redissonInstance = setupRedis();
}
return _redissonInstance;
}
public static void setRedisHost(String redisHost) {
_logger.warn("Setting REDIS_HOST to: " + redisHost);
REDIS_HOST = redisHost;
}
}
【问题讨论】:
-
我想不出任何单例是个好主意的用例。
-
为什么单例在 Java 中是个坏主意?似乎我读的越多,似乎越不推荐它们(仍在学习Java btw)
-
在任何语言中它们都是一个坏主意。这就是不推荐它们的原因。谷歌已经编写了检测它们以消除它们的工具:googlecode.blogspot.com/2007/07/…
-
总体上同意@nikdeapen 的观点,即
public static final对于拥有如此多资源(TCP 连接、线程等)的实例来说是一个糟糕的选择。任何主要保存在static final中的实例都无法以合理的方式进行管理。 Spring、CDI 或 EJB 中的单例更好,因为您可以通过 bean 管理来初始化和销毁实例。使用static final需要您自己关闭实例或添加关闭挂钩。 -
@mp911de 我明白你的意思,谢谢!您是否知道如何在 Jetty Servlet 中进行设置?我已将 MySql 数据源设置为 JDNI 资源,但似乎找不到为 redis 设置资源的方法