Bean named 'defaultSockJsTaskScheduler' is expected to be of type 'org.springframework.scheduling.

錯誤詳情:

springboot + quartz + websocket (spring 自帶得websocket 模塊) 引起的衝突問題

 contextLoads(com.kzcm.higo.HigoApplicationTests)  Time elapsed: 0.033 s  <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: 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'

 環境配置:

springboot + quartz 定時任務 + websocket (spring 自帶得websocket 模塊)

說明:

集成自網上下載得一個 layui 後臺管理框架,當沒用把 websocket 模塊加入項目中得時候,項目可以正常啓動,但是加入之後就報錯,一直以爲是 quartz 本身得問題,把quartz得sql 表重新執行了幾次還是不能啓動,後來用mvn 打包才報出最上面得錯誤,才定位到是websocket 模塊得問題,下面得報錯是springboot 得報錯,根本無從找起

Exception in thread "Quartz Scheduler [MySiteForMeScheduler]" org.springframework.scheduling.SchedulingException: Could not start Quartz Scheduler after delay; nested exception is org.quartz.SchedulerException: The Scheduler cannot be restarted after shutdown() has been called.
	at org.springframework.scheduling.quartz.SchedulerFactoryBean$1.run(SchedulerFactoryBean.java:753)
Caused by: org.quartz.SchedulerException: The Scheduler cannot be restarted after shutdown() has been called.
	at org.quartz.core.QuartzScheduler.start(QuartzScheduler.java:529)
	at org.quartz.impl.StdScheduler.start(StdScheduler.java:142)
	at org.springframework.scheduling.quartz.SchedulerFactoryBean$1.run(SchedulerFactoryBean.java:750)

參考: https://www.cnblogs.com/threadj/articles/10631193.html

參考: https://blog.csdn.net/u013565163/article/details/80659828

參考: https://stackoverflow.com/questions/56169448/scheduled-task-not-working-with-websockets

問題定位:

最後全劇搜索 DefaultSockJsTaskScheduler ,通過搜索類得方式發現再

<dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-websocket</artifactId>
       <version>5.1.8.RELEASE</version>
       <scope>compile</scope>
</dependency>

這個依賴中 org.springframework.web.socket.config.annotation.WebSocketConfigurationSupport 有一個生成定時器類的方法,最後一個方法

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.socket.config.annotation;

import org.springframework.context.annotation.Bean;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.Assert;
import org.springframework.web.servlet.HandlerMapping;

public class WebSocketConfigurationSupport {
    @Nullable
    private ServletWebSocketHandlerRegistry handlerRegistry;
    @Nullable
    private TaskScheduler scheduler;

    public WebSocketConfigurationSupport() {
    }

    @Bean
    public HandlerMapping webSocketHandlerMapping() {
        ServletWebSocketHandlerRegistry registry = this.initHandlerRegistry();
        if (registry.requiresTaskScheduler()) {
            TaskScheduler scheduler = this.defaultSockJsTaskScheduler();
            Assert.notNull(scheduler, "Expected default TaskScheduler bean");
            registry.setTaskScheduler(scheduler);
        }

        return registry.getHandlerMapping();
    }

    private ServletWebSocketHandlerRegistry initHandlerRegistry() {
        if (this.handlerRegistry == null) {
            this.handlerRegistry = new ServletWebSocketHandlerRegistry();
            this.registerWebSocketHandlers(this.handlerRegistry);
        }

        return this.handlerRegistry;
    }

    protected void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    }

    @Bean
    @Nullable
    public TaskScheduler defaultSockJsTaskScheduler() {
        if (this.initHandlerRegistry().requiresTaskScheduler()) {
            ThreadPoolTaskScheduler threadPoolScheduler = new ThreadPoolTaskScheduler();
            threadPoolScheduler.setThreadNamePrefix("SockJS-");
            threadPoolScheduler.setPoolSize(Runtime.getRuntime().availableProcessors());
            threadPoolScheduler.setRemoveOnCancelPolicy(true);
            this.scheduler = threadPoolScheduler;
        }

        return this.scheduler;
    }
}

解決:

在 quart的配置類中手動增加 對應的 引入@Bean

    @Bean
    @Nullable
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler threadPoolScheduler = new ThreadPoolTaskScheduler();
            threadPoolScheduler.setThreadNamePrefix("SockJS-");
            threadPoolScheduler.setPoolSize(Runtime.getRuntime().availableProcessors());
            threadPoolScheduler.setRemoveOnCancelPolicy(true);
        return threadPoolScheduler;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章