如何确保只创建一个XMPPConnection?使用单身人士?

时间:2011-09-28 16:46:13

标签: java design-patterns singleton xmpp smack

我正在处理创建一个Web服务,该服务将接收通过XMPP发送消息的请求。但是,所有邮件都将从一个帐户发送(服务器登录并向用户发送通知)。

问题出现了 - 如何实现?我试图将XMPPConnection类实现为单例,但我不得不将参数传递给包含主机名,端口,JID等的构造函数

正如我读过here带参数的单身人士不是单身人士 ...因此,我想要解决它如下(是某种工厂吗?) :

public class XMPPConnectionSingleton
{
    private volatile static XMPPConnectionSingleton anInstance;
    private volatile static XMPPConnection connection;

    public static XMPPConnectionSingleton getInstance() {
        if(anInstance == null) {
            synchronized (XMPPConnectionSingleton.class) {
                if(anInstance == null)
                    anInstance = new XMPPConnectionSingleton();
            }
        }
        return anInstance;
    }

    public void init(String server, int port, String jid, String password, String resource)
    {
        ConnectionConfiguration conf = new ConnectionConfiguration(server, port);
        connection = new XMPPConnection(conf);
        // logging in, etc.
    }
}

这是一个好方法吗?或者最好为XMPPConnection创建一个包装类,接受一个没有参数的构造函数?

2 个答案:

答案 0 :(得分:0)

您可以使用〜单身,阅读此question以及相关网页herehere。最干净的是在静态块中初始化,但这并不总是可行的。

这种直观,简单的方法是在单个实例上进行同步,并且所有WS调用都在等待。这对于低容量非常有用。使用ReentrantLock可能会在某种程度上增强该逻辑 - 例如发送超时WS响应而不是整个HTTP调用。

如果您需要多个并发会话,请考虑检查服务器是否可以使用多个客户端登录,然后根据需要初始化任意数量的客户端 - 然后以某种方式使用ReentrantLock来确定当前免费的客户端。

根据WS调用中的逻辑(是否需要确认消息是否发送到XMPP?),您可能会考虑将调用排队并从另一个线程提供服务,在发送实际消息之前返回WS调用(http保持时间通常为30秒,但可以更改。)

甚至可以让每个WS会话在呼叫期间连接并拥有自己的会话。

编辑:我建议您选择

// Correct lazy initialization in Java 
@ThreadSafe
class Foo {
    private static class HelperHolder {
       public static Helper helper = new Helper();
    }

    public static Helper getHelper() {
        return HelperHolder.helper;
    }
}

Helper在哪里

  1. 从某个地方提取登录信息的帮助程序类,包装XMPP客户端类,或
  2. XMPP客户端类本身带有硬编码登录信息。
  3. 然后只需在返回的对象上使用synchronized运算符。

答案 1 :(得分:0)

听起来像是错误的做法。为什么不简单地将WS请求放入队列并让单个线程读取请求并通过xmpp写入消息。只有一个连接,但根本不需要创建任何自定义代码来创建单例连接。