我有一个使用 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/