Java 无法在服务器关闭期间停止Bean

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

我有一个利用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 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);
}