我有一个使用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
。
我不确定为什么这个豆子不会停止以及我做错了什么。
答案 0 :(得分:1)
因为它不适合评论而移到这里。我无法证明,但似乎正在发生的事情:
AccountEventPublisherConfig.publisher
是应用程序上下文。
但是,AccountEventPublisherConfig.simplePublisher()
创建了一个名为“accountEventPublisher”的托管bean,它实际上是应用程序上下文的别名。
当停止应用程序时,上下文正在尝试关闭“accountEventPublisher”bean,它本身就是这样。这可能导致以StackOverflowError结束的递归调用。
尝试删除“accountEventPublisher”bean的定义。在服务中:
@Autowired
private ApplicationEventPublisher accountEventPublisher;
并直接发布:
public static void sendEvent(ApplicationEvent event) {
accountEventPublisher.publishEvent(event);
}
答案 1 :(得分:0)
我能够解决问题。我最终不得不将配置类更改为组件并实现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;
}
}
然后我修改了对其他发布者的引用,它似乎有效。不再收到错误。