Как реализовать SmartLifecycleRoleController в приложении Spring Integration - PullRequest
0 голосов
/ 30 августа 2018

Я пишу клиент-серверное приложение на основе конечных точек int-ip: tcp. Код написан на Kotlin. Приложение содержит два клиента tcp, которые должны устанавливать соединение с сервером в определенной последовательности, один за другим, когда первая очистка уже установила соединение с сервером и произвела некоторую инициализацию.

В качестве решения для этой синхронизации я предполагаю использовать SmartLifecycleRoleController для запуска группы конечных точек зависимого tcp-клиента. Для этого в зависимом (втором) клиенте я добавляю атрибуты role="rcCluster" и auto-startup="false" в tcp-outbound-channel-adapter и tcp-inbound-channel-adapter

<int-ip:tcp-connection-factory id="rcClientConnectionFactory"
                               type="client"
                               host="${tdirelay.host}"
                               port="${tdirelay.rcPort}"
                               single-use="false"
                               so-timeout="10000"
                               so-keep-alive="false"
                               serializer="rawSerializerDeserializer"
                               deserializer="rawSerializerDeserializer"
                               ssl-context-support="sslContext"/>


<int-ip:tcp-outbound-channel-adapter id="rcOutBoundAdapter"
                                     channel="rcPacketQueueChannel"
                                     phase="5000"
                                     connection-factory="rcClientConnectionFactory"
                                     role="rcCluster"
                                     auto-startup="false"
/>


<int-ip:tcp-inbound-channel-adapter id="rcInboundAdapter"
                                    channel="rcFromServer"
                                    client-mode="true"
                                    retry-interval="5000"
                                    connection-factory="rcClientConnectionFactory"
                                    role="rcCluster"
                                    auto-startup="false"


/>  

Ведущий (первый) tcp-клиент использует конечную точку перехватчика для обмена прологом с сервером в соответствии с протоколом:

<bean id="dcInterceptorFactoryChain"
      class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
    <property name="interceptors">
        <array>
            <bean class="com.tcpclient.DirectCannel.DCConnectionInterceptorFactory">
            </bean>
        </array>
    </property>
</bean>


<int-ip:tcp-connection-factory id="dcClientConnectionFactory"
                               type="client"
                               host="${tdirelay.host}"
                               port="${tdirelay.dcPort}"
                               single-use="false"
                               so-timeout="10000"
                               so-keep-alive="false"
                               interceptor-factory-chain="dcInterceptorFactoryChain"
                               serializer="rawSerializerDeserializer"
                               deserializer="rawSerializerDeserializer"
                               ssl-context-support="sslContext"
/>

Я планирую вызвать startLifecyclesInRole(String role) и stopLifecyclesInRole(String role) методы SmartLifecycleRoleController внутри моего класса Interceptor. Итак, я добавил @Autowired private val roleController: SmartLifecycleRoleController в InterceptorFactory, как объяснено в spring -gration / docs

Мой завод-перехватчик:

class DCConnectionInterceptorFactory() : TcpConnectionInterceptorFactory, ApplicationEventPublisherAware {

    @Autowired
    private val roleController: SmartLifecycleRoleController? = null

    @Volatile
    private var applicationEventPublisher: ApplicationEventPublisher? = null

    override fun setApplicationEventPublisher(applicationEventPublisher: ApplicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher
    }

    override fun getInterceptor(): TcpConnectionInterceptorSupport {
        return DCConnectionInterceptor(this.applicationEventPublisher!!, roleController!!)
    }
}

IntelliJ IDEA выдает предупреждение: Не удалось автопровода. Не найдено бобов типа «SmartLifecycleRoleController»

И здание дает ошибку:

[task-scheduler-2] ОШИБКА org.springframework.integration.ip.tcp.connection.ClientModeConnectionManager - Не удалось установить соединение с помощью dcClientConnectionFactory, host = localhost, port = 9001 kotlin.KotlinNullPointerException at com.tcpclient.DirectCannel.DCConnectionInterceptorFactory.getInterceptor (DCConnectionInterceptorFactory.kt: 25)

Полагаю, мне нужно определить bean-компонент типа SmartLifecycleRoleController в файле конфигурации xml (это не упоминается в документации: https://docs.spring.io/spring-integration/docs/4.3.4.RELEASE/reference/html/messaging-endpoints-chapter.html#endpoint-roles). Конструктор этого класса имеет аргументы: public SmartLifecycleRoleController (список ролей, список жизненных циклов) который я не знаю, как заполнить мое дело в XML-файле:

Если вы знаете, как это сделать, приведите пример использования bean-компонента класса SmartLifecycleRoleController в файле конфигурации xml.

1 Ответ

0 голосов
/ 30 августа 2018

Прежде всего было бы лучше вообще не использовать @Autowired, поскольку неясно, включена ли конфигурация аннотации в контексте вашего приложения или нет. Только потому, что вы показываете только XML-конфигурацию для Spring.

Поэтому ваш DCConnectionInterceptorFactory должен иметь установщик для этого свойства roleController. Или как правильно объявить свойства Java-бина в Kotlin ...

Тогда вам нужно использовать что-то подобное в вашей конфигурации XML:

<bean class="com.tcpclient.DirectCannel.DCConnectionInterceptorFactory">
    <property name="roleController" ref="integrationLifecycleRoleController"/>
</bean>

Framework создает для вас SmartLifecycleRoleController автоматически и регистрирует его с указанным именем IntegrationContextUtils.INTEGRATION_LIFECYCLE_ROLE_CONTROLLER bean.

Пожалуйста, поднимите JIRA по этому вопросу, чтобы улучшить документацию, чтобы сделать ее намного чище.

Кстати, ваш подход верен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...