14

我正在尝试在 Java 中使用带有 SSL 的自定义 SocketImpl。因此,我需要设置 ServerSocket 的套接字工厂。我现在注意到它是静态的,这给我带来了一些麻烦,因为我想为它提供一些在每个 ServerSocket 实例中不同的参数。有谁知道使它成为静态的原因?对我来说,这感觉像是一个不必要的约束,只会在你的应用程序中引入更多的全局状态。

更新 为什么这很麻烦似乎有些困惑。这造成的问题是它迫使我在整个应用程序中使用同一个工厂。如果我想在一个地方使用默认的 SocketImpl 而在另一个地方使用自定义的怎么办?如果不求助于一些丑陋的反射黑客就无法做到这一点,因为工厂一旦设置就无法更改。我也不能让我的工厂创建默认实现,因为 SocksSocketImpl 是包私有的。

4

6 回答 6

4

SocketImpl 是一个抽象类,它提供了一个用于自定义套接字实现的接口。SocketImpl 的子类不打算显式实例化。相反,它们是由 SocketImplFactory 创建的。这种设计的动机是允许您通过调用 Socket.setSocketImplFactory() 来更改整个应用程序使用的默认套接字类型,从而无需重写所有网络代码。SSL 和防火墙隧道等功能需要自定义套接字。不幸的是,setSocketImplFactory() 的全局特性相当有限,因为它不允许您在单个应用程序中使用多种类型的套接字。您可以通过继承 Socket 并使用 JDK 1.1 中引入的受保护的 Socket(SocketImpl) 构造函数来解决这个问题。

参考: http: //www.devx.com/tips/Tip/26363

于 2012-08-22T11:34:18.147 回答
1

看来,拥有这个静态设置器似乎更容易使用,因为不需要有 ServerSocket 的实例,它可以让您设置 Socket 工厂而无需引用它。我认为让这个 setter 全局化使得它实际上更容易实现,为什么对你来说很麻烦?

于 2012-08-22T11:05:31.310 回答
1

ServerSocket的构造函数

如果应用程序指定了服务器套接字工厂,则调用该工厂的 createSocketImpl 方法来创建实际的套接字实现。否则会创建一个“普通”套接字。

所以它必须是静态的,因为如果您希望在创建套接字的新实例时使用它,则必须设置工厂。

于 2012-08-22T11:07:22.867 回答
1

It's pretty disgusting, but you could create a DelegatingSocketFactory that looks back up the call stack at who called it, and either creates a SocksSocketImpl (using reflection to sort out the accessibility), or uses the Ice4J one. This counts as a reflection hack!

于 2012-08-29T07:54:46.333 回答
0

您是否希望非静态工厂知道如何神奇地实例化您的自定义类?

于 2012-08-28T10:30:17.843 回答
0

在我看来,这似乎是 的经典案例Factory Pattern,其中您提供了一个自定义工厂对象,其设置指示如何创建某个类的实例。将工厂操作为静态的方法非常有意义,因为工厂充当“元对象”,指导其他对象的创建。

从设计的角度来看,拥有每个实例的工厂根本没有意义。每个实例拥有不同的工厂有什么意义?您是否打算ServerSocket从其他实例创建实例?如果您想要不同的设置,您只需每次提供不同的工厂。

于 2012-08-29T07:27:07.563 回答