Java 无法在服务器关闭期间停止Bean
我有一个利用spring和stomp消息的war文件。一切都很好,但在关机或重启期间,我看到数百行,如:Java 无法在服务器关闭期间停止Bean,java,spring,Java,Spring,我有一个利用spring和stomp消息的war文件。一切都很好,但在关机或重启期间,我看到数百行,如: 07-Feb-2018 12:21:35.929 [INFO ] Stopping beans in phase 0 07-Feb-2018 12:21:35.929 [INFO ] Stopping beans in phase 2147483647 07-Feb-2018 12:21:35.929 [INFO ] Stopping beans in phase 0 07-Feb-2018
07-Feb-2018 12:21:35.929 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.929 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.929 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.929 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.929 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.930 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.930 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.930 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.930 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.930 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.931 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.931 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.931 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.931 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.931 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.932 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.932 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.932 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.932 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.933 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:35.933 [INFO ] Stopping beans in phase 0
07-Feb-2018 12:21:35.933 [INFO ] Stopping beans in phase 2147483647
07-Feb-2018 12:21:36.394 [WARN ] Failed to stop bean 'accountEventPublisher'
java.lang.StackOverflowError: null
My accountEventPublisher bean发布事件以允许服务器的其他部分截获事件并对其执行操作
这是我的accountEventPublisherBean:
@Configuration
public class AccountEventPublisherConfig {
public static final String MULTICAST_NAME = "accountEventMulticaster";
public static final String EVENT_PUBLISHER_NAME ="accountEventPublisher";
@Autowired
private ApplicationEventPublisher publisher;
@Bean(name=MULTICAST_NAME)
public ApplicationEventMulticaster simpleApplicationEventMulticaster() {
SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster();
eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor());
return eventMulticaster;
}
@Bean(name=EVENT_PUBLISHER_NAME)
public ApplicationEventPublisher simplePublisher() {
return publisher;
}
}
然后在静态通信服务中使用它发送事件:
@Service
public class CommService {
private static ApplicationEventPublisher accountEventPublisher;
public static void sendEvent(ApplicationEvent event) {
if (accountEventPublisher== null) {
accountEventPublisher = (ApplicationEventPublisher) ApplicationContextHolder.getContext().getBean(AccountEventPublisherConfig.EVENT_PUBLISHER_NAME);
}
accountEventPublisher.publishEvent(event);
}
}
以下代码是截获事件的代码
@Component
public class FileUploadTriggerListener implements ApplicationListener<AccountTrigger> {
@Autowired
private PatchFileService fileService;
@Autowired
private ApplicationLogService appLogService;
@Autowired
private ExecutorService executor;
@Override
public void onApplicationEvent(AccountTrigger trigger) {
if (trigger.getType() != TriggerType.FILE_UPLOADED) return;
executor.schedule(new Runnable() {
@Override
public void run() {
System.out.println("Hello World");
});
}
}
}
所有ApplicationEvents的类型均为带有触发器类型枚举的AccountTrigger。我现在使用的唯一触发器类型是FILE\u UPLOAD
我不知道为什么这个bean不会停止,我做错了什么。我能够解决这个问题。最后,我不得不将配置类更改为一个组件并实现
ApplicationEventPublisherAware
@Component
public class AccountEventPublisher implements ApplicationEventPublisherAware {
public static final String EVENT_PUBLISHER_NAME ="accountEventPublisher";
private ApplicationEventPublisher publisher;
public void publishEvent(AccountTrigger event) {
publisher.publishEvent(event);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
publisher = applicationEventPublisher;
}
}
然后我修正了对另一家出版商的引用,这似乎奏效了。不再获取错误。移动到此处,因为它不适合评论。我无法证明,但似乎发生了什么:
AccountEventPublisherConfig.publisher
是应用程序上下文
但是,AccountEventPublisherConfig.simplePublisher()
创建一个名为“accountEventPublisher”的托管bean,它本质上是应用程序上下文的别名
停止应用程序时,上下文试图关闭“accountEventPublisher”bean,该bean本身就是。这可能导致递归调用以StackOverflowerError结尾
尝试删除“accountEventPublisher”bean的定义。在服务中:
@Autowired
private ApplicationEventPublisher accountEventPublisher;
并直接发布:
public static void sendEvent(ApplicationEvent event) {
accountEventPublisher.publishEvent(event);
}
您可以发布
ApplicationEventPublisher
类吗。它是否管理需要关闭的资源?ApplicationEventPublisher
是spring提供的一个接口,我从中得到了一个示例。我添加了截取事件的代码。啊,谢谢你,我从没想过。这是有道理的。我确实通过ApplicationEventPublisherAware
找到了解决问题的另一种方法,但您的评论解释了发生的情况。
public static void sendEvent(ApplicationEvent event) {
accountEventPublisher.publishEvent(event);
}