java - 服务器关闭期间无法停止 Bean

标签 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 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

我的 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;
  }
}

然后我在静态 CommService 中使用它来发送事件:

@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");
      });
    }
  }
}

这是扩展 ApplicationEvent 的类

public class AccountTrigger extends ApplicationEvent {

  private static final long serialVersionUID = 2139401946845273241L;

  private Integer userId;

  private TriggerType type;

  private List<Object> resources = new ArrayList<>();

  public Integer getUserId() {
    return userId;
  }

  public void setUserId(Integer userId) {
    this.userId = userId;
  }

  public List<Object> getResources() {
    return resources;
  }

  public void setResources(List<Object> resources) {
    this.resources = resources;
  }

  public TriggerType getType() {
    return type;
  }

  public void setType(TriggerType type) {
    this.type = type;
  }
}

所有 ApplicationEvent 的类型均为 AccountTrigger,并带有触发器类型的枚举。我现在使用的唯一触发器类型是FILE_UPLOAD

我不确定为什么这个 bean 不会停止以及我做错了什么。

最佳答案

移至此处,因为它不适合评论。我无法证明,但似乎正在发生什么:

AccountEventPublisherConfig.publisher 是应用程序上下文。

此外,AccountEventPublisherConfig.simplePublisher() 创建一个名为“accountEventPublisher”的托管 Bean,它本质上是应用程序上下文的别名。

停止应用程序时,上下文会尝试关闭“accountEventPublisher”bean,即它本身。这可能会导致递归调用以 StackOverflowError 结束。

尝试删除“accountEventPublisher”bean 的定义。在服务中:

@Autowired 
private ApplicationEventPublisher accountEventPublisher;

并直接发布:

public static void sendEvent(ApplicationEvent event) {
     accountEventPublisher.publishEvent(event);
}

关于java - 服务器关闭期间无法停止 Bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48671293/

相关文章:

java - Grails:持久后变旧实例

java - JAX_RS-MessageBodyProviderNotFoundException : MessageBodyWriter not found for ArrayList

java - 在C++中模拟Java的Thread类

Spring - java.lang.NoSuchMethodError : org. springframework.web.accept.ContentNegotiationManager.getStrategies()Ljava/util/List;?

Spring 父子资源

java - 如何通过函数传递枚举定义并在 java 中访问其成员?

java - 使用大日志启动时 HornetQ OutOfMemory

java - maven编译错误

java - Spring MVC 导航

java - 如何使用两个属性作为key的spring缓存