一、项目背景
根据项目需求要使用定时任务+WebSocket不断的往前台推送数据。当项目同时集成WebSocket+定时任务时会报错:Bean named 'defaultSockJsTaskScheduler' is expected to be of type···,报错信息如下
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'defaultSockJsTaskScheduler' is expected to be of type 'org.springframework.scheduling.TaskScheduler' but was actually of type 'org.springframework.beans.factory.support.NullBean'
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:395) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:227) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1172) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1139) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.resolveSchedulerBean(ScheduledAnnotationBeanPostProcessor.java:315) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.finishRegistration(ScheduledAnnotationBeanPostProcessor.java:256) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:233) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:105) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.1.RELEASE.jar:2.3.1.RELEASE]
at com.niutrans.localdeploymentserver.LocalDeploymentServerApplication.main(LocalDeploymentServerApplication.java:19) [classes/:na]二、处理过程回顾
定时任务选择的是Spring自带的定时任务,先在项目中集成了WebSocket,编译,运行,测试后,功能好用。但是再加上定时任务后就报错了。
启动类代码如下:
@SpringBootApplication
@EnableWebSocket
@EnableScheduling
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TrainbasicserverApplication.class, args);
}
}三、解决方案
手动添加一个定时任务的配置类来创建一个ThreadPoolTaskScheduler对象。
@Configuration
public class ScheduledConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduling = new ThreadPoolTaskScheduler();
scheduling.setPoolSize(10);
scheduling.initialize();
return scheduling;
}
}四、为什么
大致猜测,仅供参考!!!
报错大致意思是:名为'defaultSockJsTaskScheduler'的Bean应为'org.springframework.scheduling.TaskScheduler“但实际上是类型”org.springframework.beans.factory.support.NullBean'。这个异常是由(AbstractBeanFactory.java:395)抛出的。
启动时还会出现警告
2021-01-15 13:28:37.245 WARN 140 --- [ main] o.a.c.loader.WebappClassLoaderBase : The web application [ROOT] appears to have started a thread named [ForkJoinPool.commonPool-worker-3] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824)
java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693)
java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
警告大致意思是:web应用程序[ROOT]似乎启动了一个名为[ForkJoinPool.commonPool-worker-3]但是不能停止这个线程。这很可能会造成内存泄漏。
websocket需要创建线程,定时任务也需要创建线程,应该是websocket和定时任务在创建线程的时候发生了冲突,定时任务创建线程没有成功。
这个时候我们手动创建一个定时任务的线程池,使得定时任务使用自己的线线程池,就能解决冲突。
版权声明:本文为weixin_40877388原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。