实施正常关机功能时面临的问题

时间:2019-06-13 04:55:55

标签: spring-boot spring-integration

我正在研究独立的Spring Boot应用程序,并使用Spring集成通道体系结构将文件从源传输到目标。 我们还提供了多实例功能,要实现此目的,我们将锁定(为文件附加.lock)特定实例的文件,以限制来自其他实例的访问。 目前,我有一个正常关机的要求。我实现了,但最终遇到以下错误。有人可以帮我吗?

Control bus configuration :

<integration:channel id="controlChannel" />
<integration:control-bus input-channel="controlChannel" />

Adapter configuration :

<file:inbound-channel-adapter id="filesInChannel"
        directory="path" auto-startup="false" scanner="recursiveScanner"
        auto-create-directory="true">
        <integration:poller id="poller"
            max-messages-per-poll="5" fixed-rate="1000" 
            task-executor="pollingExecutor">
            <integration:transactional
                transaction-manager="transactionManager" />
        </integration:poller>
    </file:inbound-channel-adapter>

Method added for graceful shutdown component
@PreDestroy
    public void onDestroy() throws InterruptedException {

        try {
            inboundFileAdapterChannel.send(new GenericMessage<String>("@'filesInChannel.adapter'.stop()"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        // wait till current processing of files is over
        pollingExecutor.shutdown();
        pollingExecutor.setWaitForTasksToCompleteOnShutdown(Boolean.TRUE);
        System.out.println("Application shutdown succesfully");
    }

错误跟踪:

org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application.controlChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=GenericMessage [payload=@'filesInChannel.adapter'.stop(), headers={id=5f0282c5-5a02-3f57-3056-948dd74a8d72, timestamp=1559894703464}], failedMessage=GenericMessage [payload=@'filesInChannel.adapter'.stop(), headers={id=5f0282c5-5a02-3f57-3056-948dd74a8d72, timestamp=1559894703464}]
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:445)
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:394)
        at com.openbank.interfaces.file.handler.GracefulShutdownHook.onDestroy(GracefulShutdownHook.java:63)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:365)
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeDestroyMethods(InitDestroyAnnotationBeanPostProcessor.java:323)
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeDestruction(InitDestroyAnnotationBeanPostProcessor.java:155)
        at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:240)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:577)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:549)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:957)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:510)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:964)
        at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1041)
        at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1017)
        at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:937)
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers, failedMessage=GenericMessage [payload=@'filesInChannel.adapter'.stop(), headers={id=5f0282c5-5a02-3f57-3056-948dd74a8d72, timestamp=1559894703464}]
        at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:138)
        at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105)
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73)
        ... 19 more

1 个答案:

答案 0 :(得分:1)

@PreDestroy来不及执行此类操作。

到那时,所有Lifecyle bean都将被stop()填充(从频道退订)。

您需要使用其他信号来执行这项工作。

您可以实现SmartLifecyle并将您的bean放在后期(这样就stop()尽早使用了。