Advanced Techniques

  • TcpSSLContextSupport:负责创建 SSLContext 对象。

  • TcpSocketFactorySupport:负责获取对 ServerSocketFactory 和 SocketFactory 的引用。

  • TcpSocketSupport:允许在套接字创建后修改套接字。

  • TcpNetConnectionSupport:用于创建连接对象。

  • TcpNioConnectionSupport:用于在使用 NIO 时创建连接对象。

文章重点介绍了如何使用这些接口来对套接字进行高级配置,例如启用 SSL 客户端证书身份验证。

此部分介绍了您在特定情况下可能觉得有用的高级技术。

This section covers advanced techniques that you may find to be helpful in certain situations.

Strategy Interfaces

在许多情况下,前面描述的配置是实现 TCP/IP 上的安全通信所需的所有内容。但是,Spring Integration 提供了一些策略接口,允许自定义和修改套接字工厂和套接字:

In many cases, the configuration described earlier is all that is needed to enable secure communication over TCP/IP. However, Spring Integration provides a number of strategy interfaces to allow customization and modification of socket factories and sockets:

  • TcpSSLContextSupport

  • TcpSocketFactorySupport

  • TcpSocketSupport

  • TcpNetConnectionSupport

  • TcpNioConnectionSupport

The TcpSSLContextSupport Strategy Interface

以下列表显示了 TcpSSLContextSupport 策略接口:

The following listing shows the TcpSSLContextSupport strategy interface:

public interface TcpSSLContextSupport {

    SSLContext getSSLContext() throws Exception;

}

TcpSSLContextSupport`接口的实现负责创建 `SSLContext`对象。框架提供的实现是 `DefaultTcpSSLContextSupportdescribed earlier。如果需要不同的行为,请实现这个接口并提供一个对代表你类实现的 bean 的引用的连接工厂。

Implementations of the TcpSSLContextSupport interface are responsible for creating an SSLContext object. The implementation provided by the framework is the DefaultTcpSSLContextSupport, described earlier. If you require different behavior, implement this interface and provide the connection factory with a reference to a bean of your class' implementation.

The TcpSocketFactorySupport Strategy Interface

以下列表显示了 TcpSocketFactorySupport 策略接口的定义:

The following listing shows the definition of the TcpSocketFactorySupport strategy interface:

public interface TcpSocketFactorySupport {

    ServerSocketFactory getServerSocketFactory();

    SocketFactory getSocketFactory();

}

此接口的实现负责获取对 ServerSocketFactorySocketFactory 的引用。提供了两个实现。第一个是用于非 SSL 套接字的 DefaultTcpNetSocketFactorySupport(当不定义 ssl-context-support 属性时)。这使用 JDK 的默认工厂。第二个实现是 DefaultTcpNetSSLSocketFactorySupport。默认情况下,当定义 ssl-context-support 属性时使用此实现。它使用该 bean 创建的 SSLContext 来创建套接字工厂。

Implementations of this interface are responsible for obtaining references to ServerSocketFactory and SocketFactory. Two implementations are provided. The first is DefaultTcpNetSocketFactorySupport for non-SSL sockets (when no ssl-context-support attribute is defined). This uses the JDK’s default factories. The second implementation is DefaultTcpNetSSLSocketFactorySupport. By default, this is used when an ssl-context-support attribute is defined. It uses the SSLContext created by that bean to create the socket factories.

此接口仅适用于 using-niofalse 的情况。NIO 不使用套接字工厂。

This interface applies only if using-nio is false. NIO does not use socket factories.

The TcpSocketSupport Strategy Interface

以下列表显示了 TcpSocketSupport 策略接口的定义:

The following listing shows the definition of the TcpSocketSupport strategy interface:

public interface TcpSocketSupport {

    void postProcessServerSocket(ServerSocket serverSocket);

    void postProcessSocket(Socket socket);

}

此接口的实现可以在套接字创建后、应用所有配置的属性后、但在使用套接字之前,修改套接字。这无论您是否使用 NIO 都适用。例如,您可以使用此接口的实现来修改 SSL 套接字上的受支持密码套件,或者可以添加一个侦听器,在 SSL 握手完成后通知该侦听器。框架提供的唯一实现是 DefaultTcpSocketSupport,它不会以任何方式修改套接字。

Implementations of this interface can modify sockets after they are created and after all configured attributes have been applied but before the sockets are used. This applies whether you use NIO or not. For example, you could use an implementation of this interface to modify the supported cipher suites on an SSL socket, or you could add a listener that gets notified after SSL handshaking is complete. The sole implementation provided by the framework is the DefaultTcpSocketSupport, which does not modify the sockets in any way.

要提供自己的 TcpSocketFactorySupportTcpSocketSupport 实现,请向连接工厂提供对自定义类型的 bean 的引用,分别设置 socket-factory-supportsocket-support 属性。

To supply your own implementation of TcpSocketFactorySupport or TcpSocketSupport, provide the connection factory with references to beans of your custom type by setting the socket-factory-support and socket-support attributes, respectively.

The TcpNetConnectionSupport Strategy Interface

以下列表显示了 TcpNetConnectionSupport 策略接口的定义:

The following listing shows the definition of the TcpNetConnectionSupport strategy interface:

public interface TcpNetConnectionSupport {

    TcpNetConnection createNewConnection(Socket socket,
            boolean server, boolean lookupHost,
            ApplicationEventPublisher applicationEventPublisher,
            String connectionFactoryName) throws Exception;

}

调用此接口以创建 TcpNetConnection(或其子类)类型的对象。该框架提供了一个单一实现(DefaultTcpNetConnectionSupport),默认情况下,它创建简单的 TcpNetConnection 对象。它有两个属性:pushbackCapablepushbackBufferSize。启用回推时,该实现返回一个子类,该子类将连接的 InputStream 封装在 PushbackInputStream 中。与 PushbackInputStream 默认值保持一致,缓冲区大小默认为 1。这允许反序列化器“未读取”(回推)流中的字节。以下平凡的示例演示了它如何在委托反序列化器中使用,该委托反序列化器“窥视”第一个字节以确定要调用的反序列化器:

This interface is invoked to create objects of type TcpNetConnection (or its subclasses). The framework provides a single implementation (DefaultTcpNetConnectionSupport), which, by default, creates simple TcpNetConnection objects. It has two properties: pushbackCapable and pushbackBufferSize. When push back is enabled, the implementation returns a subclass that wraps the connection’s InputStream in a PushbackInputStream. Aligned with the PushbackInputStream default, the buffer size defaults to 1. This lets deserializers “unread” (push back) bytes into the stream. The following trivial example shows how it might be used in a delegating deserializer that “peeks” at the first byte to determine which deserializer to invoke:

public class CompositeDeserializer implements Deserializer<byte[]> {

    private final ByteArrayStxEtxSerializer stxEtx = new ByteArrayStxEtxSerializer();

    private final ByteArrayCrLfSerializer crlf = new ByteArrayCrLfSerializer();

    @Override
    public byte[] deserialize(InputStream inputStream) throws IOException {
        PushbackInputStream pbis = (PushbackInputStream) inputStream;
        int first = pbis.read();
        if (first < 0) {
            throw new SoftEndOfStreamException();
        }
        pbis.unread(first);
        if (first == ByteArrayStxEtxSerializer.STX) {
            this.receivedStxEtx = true;
            return this.stxEtx.deserialize(pbis);
        }
        else {
            this.receivedCrLf = true;
            return this.crlf.deserialize(pbis);
        }
    }

}

The TcpNioConnectionSupport Strategy Interface

以下列表显示了 TcpNioConnectionSupport 策略接口的定义:

The following listing shows the definition of the TcpNioConnectionSupport strategy interface:

public interface TcpNioConnectionSupport {

    TcpNioConnection createNewConnection(SocketChannel socketChannel,
            boolean server, boolean lookupHost,
            ApplicationEventPublisher applicationEventPublisher,
            String connectionFactoryName) throws Exception;

}

调用此接口以创建 TcpNioConnection`对象(或来自子类的对象)。Spring Integration 提供两个实现:`DefaultTcpNioSSLConnectionSupport`和 `DefaultTcpNioConnectionSupport。使用哪个实现取决于是否使用 SSL。一个常见的用例是子类化 DefaultTcpNioSSLConnectionSupport`并覆盖 `postProcessSSLEngine。请参见 SSL client authentication example。与 `DefaultTcpNetConnectionSupport`一样,这些实现也支持回退。

This interface is invoked to create TcpNioConnection objects (or objects from subclasses). Spring Integration provides two implementations: DefaultTcpNioSSLConnectionSupport and DefaultTcpNioConnectionSupport. Which one is used depends on whether SSL is in use. A common use case is to subclass DefaultTcpNioSSLConnectionSupport and override postProcessSSLEngine. See the SSL client authentication example. As with the DefaultTcpNetConnectionSupport, these implementations also support push back.

Example: Enabling SSL Client Authentication

要在使用 SSL 时启用客户端证书身份验证,该技术取决于您是否使用 NIO。当您不使用 NIO 时,请提供一个自定义 TcpSocketSupport 实现来对服务器套接字进行后处理:

To enable client certificate authentication when you use SSL, the technique depends on whether you use NIO. When you do not NIO , provide a custom TcpSocketSupport implementation to post-process the server socket:

serverFactory.setTcpSocketSupport(new DefaultTcpSocketSupport() {

    @Override
    public void postProcessServerSocket(ServerSocket serverSocket) {
        ((SSLServerSocket) serverSocket).setNeedClientAuth(true);
    }

});

(当您使用 XML 配置时,请通过设置 socket-support 属性提供对您的 bean 的引用)。

(When you use XML configuration, provide a reference to your bean by setting the socket-support attribute).

当您使用 NIO 时,请提供一个自定义 TcpNioSslConnectionSupport 实现对 SSLEngine 进行后处理,如下例所示:

When you use NIO, provide a custom TcpNioSslConnectionSupport implementation to post-process the SSLEngine, as the following example shows:

@Bean
public DefaultTcpNioSSLConnectionSupport tcpNioConnectionSupport() {
    return new DefaultTcpNioSSLConnectionSupport(serverSslContextSupport) {

            @Override
            protected void postProcessSSLEngine(SSLEngine sslEngine) {
                sslEngine.setNeedClientAuth(true);
            }

    }
}

@Bean
public TcpNioServerConnectionFactory server() {
    ...
    serverFactory.setTcpNioConnectionSupport(tcpNioConnectionSupport());
    ...
}

(当您使用 XML 配置时,从 4.3.7 版本开始,请通过设置 nio-connection-support 属性提供对您的 bean 的引用)。

(When you use XML configuration, since version 4.3.7, provide a reference to your bean by setting the nio-connection-support attribute).