Spring任务调度器——没有类型的限定bean [org.springframework.scheduling。TaskScheduler)定义

时间:2021-09-13 02:16:41

Error: No qualifying bean of type [org.springframework.scheduling.TaskScheduler] is defined

错误:没有类型的限定bean。TaskScheduler)定义

Here is my console log:

这是我的控制台日志:

10:32:35.742 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'cronTrigger' to allow for resolving potential circular references
10:32:35.746 [localhost-startStop-1] DEBUG o.s.s.a.ScheduledAnnotationBeanPostProcessor - No @Scheduled annotations found on bean class: class org.springframework.scheduling.support.CronTrigger
10:32:35.747 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'cronTrigger'
10:32:35.747 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'taskExecutor'
10:32:35.747 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'taskExecutor'
10:32:35.747 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'webConfig'
10:32:35.749 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'taskExecutor' to allow for resolving potential circular references
10:32:35.757 [localhost-startStop-1] DEBUG o.s.s.a.ScheduledAnnotationBeanPostProcessor - No @Scheduled annotations found on bean class: class java.util.concurrent.ScheduledThreadPoolExecutor
10:32:35.757 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'taskExecutor'
10:32:35.757 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'getInternalResourceViewResolver'
10:32:35.757 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'getInternalResourceViewResolver'
10:32:35.757 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'webConfig'
10:32:35.770 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'getInternalResourceViewResolver' to allow for resolving potential circular references
10:32:35.781 [localhost-startStop-1] DEBUG o.s.s.a.ScheduledAnnotationBeanPostProcessor - No @Scheduled annotations found on bean class: class org.springframework.web.servlet.view.InternalResourceViewResolver
10:32:35.781 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'getInternalResourceViewResolver'
10:32:35.785 [localhost-startStop-1] DEBUG o.s.w.c.s.AnnotationConfigWebApplicationContext - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@31b09c11]
10:32:35.785 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'
10:32:35.788 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'delegatingApplicationListener'
10:32:35.788 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalScheduledAnnotationProcessor'
10:32:35.788 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'mvcResourceUrlProvider'
10:32:35.788 [localhost-startStop-1] DEBUG o.s.w.s.resource.ResourceUrlProvider - Looking for resource handler mappings
10:32:35.789 [localhost-startStop-1] DEBUG o.s.w.s.resource.ResourceUrlProvider - No resource handling mappings found
10:32:35.789 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'webConfig'
10:32:35.794 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'cronTrigger'
10:32:35.808 [localhost-startStop-1] DEBUG o.s.s.a.ScheduledAnnotationBeanPostProcessor - Could not find default TaskScheduler bean

//Exception Starts from here.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.scheduling.TaskScheduler] is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.finishRegistration(ScheduledAnnotationBeanPostProcessor.java:183) [spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:162) [spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.onApplicationEvent(ScheduledAnnotationBeanPostProcessor.java:85) [spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151) [spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128) [spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331) [spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:773) [spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483) [spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4726) [catalina.jar:8.0.20.B]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5162) [catalina.jar:8.0.20.B]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.0.20.B]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) [catalina.jar:8.0.20.B]
     at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) [catalina.jar:8.0.20.B]
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) [catalina.jar:8.0.20.B]
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:581) [catalina.jar:8.0.20.B]
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1683) [catalina.jar:8.0.20.B]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_45]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_45]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
10:32:35.809 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'taskExecutor'
10:32:35.827 [localhost-startStop-1] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in [servletConfigInitParams]
10:32:35.827 [localhost-startStop-1] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in [servletContextInitParams]
10:32:35.827 [localhost-startStop-1] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Searching for key 'spring.liveBeansView.mbeanDomain' in [jndiProperties]
10:32:35.827 [localhost-startStop-1] DEBUG o.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/spring.liveBeansView.mbeanDomain]
10:32:35.830 [localhost-startStop-1] DEBUG o.s.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/spring.liveBeansView.mbeanDomain] not found - trying original name [spring.liveBeansView.mbeanDomain]. javax.naming.NameNotFoundException: Name [spring.liveBeansView.mbeanDomain] is not bound in this Context. Unable to find [spring.liveBeansView.mbeanDomain].
10:32:35.830 [localhost-startStop-1] DEBUG o.springframework.jndi.JndiTemplate - Looking up JNDI object with name [spring.liveBeansView.mbeanDomain]

Here is WebConfig.java:

这是WebConfig.java:

@Configuration
@EnableScheduling
@EnableWebMvc
@ComponentScan(basePackages="com.project")
public class WebConfig implements SchedulingConfigurer 
{    
protected static final Logger slf4jLogger  = Logger.getLogger(WebConfig.class.getName());
private static final String cronExpression = "0 0 * * * ?";



/*@Bean
public MobileNotifSchedulerBean schedulerbean()
{
    return new MobileNotifSchedulerBean();
}*/

@Bean
public InternalResourceViewResolver getInternalResourceViewResolver()
{
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/jsp/");
    resolver.setSuffix(".jsp");
    resolver.setSuffix(".html");
    resolver.setSuffix(".htm");
    return resolver;
}

@Bean
CronTrigger cronTrigger() 
{
    //String timeZone = "Asia/Calcutta";

    String timeZone = null;
    HashSet<String> userTimeZonesfromDB = FetchUserTimeZones.fetchUserTimeZone();
    for (String s : userTimeZonesfromDB) 
    {
        timeZone = s;
        slf4jLogger.info(s);
    }
    return new CronTrigger(cronExpression, TimeZone.getTimeZone(timeZone));
}


@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) 
{

    taskRegistrar.addCronTask(new CronTask(new MobileNotifSchedulerBean(), cronTrigger()));
}

@Bean(destroyMethod="shutdown")
public Executor taskExecutor() 
{
    return Executors.newScheduledThreadPool(1);
}   
}

Here is my MobileNotifSchedulerBean:

这是我MobileNotifSchedulerBean:

@EnableScheduling
public class MobileNotifSchedulerBean implements Runnable 
{
protected static final Logger slf4jLogger  = Logger.getLogger(MobileNotifSchedulerBean.class.getName());


public void sendQuestionNotif() 
{
    try 
    {
        HashSet<String> reg_ids = FetchRegistrationIDs.fetchItems();
        for (String s : reg_ids) 
        {
            String REGISTRATION_IDs = s;
            slf4jLogger.info(s);                
            MobileSNSPushNotification.sendNotification(REGISTRATION_IDs);
        }
    } 
    catch (IOException e) 
    {
        //e.printStackTrace();
        slf4jLogger.error(e);
        slf4jLogger.error(e.getMessage());
        slf4jLogger.error(e.getStackTrace());
    }
}


@Override
public void run() 
{
    sendQuestionNotif();
}
}

I am using Java 8 and Spring MVC 4. I want to solve this error "No qualifying bean of type [org.springframework.scheduling.TaskScheduler] is defined" kindly help me. TIA.

我使用的是Java 8和Spring MVC 4。我想要解决这个错误“没有类型的合格bean (org.springframework.scheduling)。“TaskScheduler”的定义是“请帮助我”。TIA。

2 个解决方案

#1


3  

This exception is logged from org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.inishRegistration():

这个异常是从org. springframework.schedule . annotation.scheduledannotationbeanpostprocessor.inishregistration()中记录的。

if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) {
    Assert.state(this.beanFactory != null, "BeanFactory must be set to find scheduler by type");
    try {
        // Search for TaskScheduler bean...
        this.registrar.setTaskScheduler(this.beanFactory.getBean(TaskScheduler.class));
    }
    catch (NoSuchBeanDefinitionException ex) {
        logger.debug("Could not find default TaskScheduler bean", ex);
        // Search for ScheduledExecutorService bean next...
        try {
            this.registrar.setScheduler(this.beanFactory.getBean(ScheduledExecutorService.class));
        }
        catch (NoSuchBeanDefinitionException ex2) {
            logger.debug("Could not find default ScheduledExecutorService bean", ex);
            // Giving up -> falling back to default scheduler within the registrar...
        }
    }
}

This process attempts to set the task scheduler for the registrar. For this, it tries to find a registered scheduler bean through BeanFactory.getBean method:

此过程试图为注册者设置任务调度器。为此,它尝试通过BeanFactory查找一个已注册的调度器bean。getBean方法:

  1. Tries to find a configured TaskScheduler bean, if not found then fallbacks to->
  2. 尝试找到一个已配置的TaskScheduler bean,如果没有找到,则返回->。
  3. finding ScheduledExecutorService bean, if not found then fallbacks to->
  4. 找到ScheduledExecutorService bean,如果没有找到,则返回->。
  5. using the default scheduler within the registrar (The same is indicated in the code comment above: // Giving up -> falling back to default scheduler within the registrar...)
  6. 使用registrar内的默认调度器(在上面的代码注释中表示://放弃->返回到注册中心的默认调度器…)

If any of the TaskScheduler or ScheduledExecutorService bean is not found in the container, BeanFactory.getBean throws an exception.

如果在容器中没有发现TaskScheduler或ScheduledExecutorService bean,那么BeanFactory。getBean将抛出一个异常。

ScheduledAnnotationBeanPostProcessor in turn logs these exception with DEBUG level:

ScheduledAnnotationBeanPostProcessor将这些异常记录到DEBUG级别:

logger.debug("Could not find default TaskScheduler bean", ex);
logger.debug("Could not find default ScheduledExecutorService bean", ex);

So, in conclusion these exceptions are just logged in process of finding a fallback option for task scheduler bean, and they do not affect the execution of the application.

因此,在结论中,这些异常只是在为任务调度程序bean找到一个回退选项的过程中记录下来的,而且它们不会影响应用程序的执行。

The log level of this class can be elevated so that these DEBUG level messages are not logged like so:

这个类的日志级别可以被提升,这样这些调试级别的消息就不会被记录下来:

<!-- Elevate the log level for 'org.springframework.scheduling' since in
     process of registering the scheduled task, Spring's
     ScheduledAnnotationBeanPostProcessor tries to find TaskScheduler and
     ScheduledExecutorService beans and then fallbacks to its internal
     scheduler but in the process logs exceptions when it cannot find those
     beans registered.
-->
<logger name="org.springframework.scheduling">
    <level value="info" />
</logger>

#2


-1  

Annote your MobileNotifSchedulerBean with @Configurable. I think it will work.

请注意您的mobilenotifschedule erbean与@可配置。我想这行得通。

#1


3  

This exception is logged from org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.inishRegistration():

这个异常是从org. springframework.schedule . annotation.scheduledannotationbeanpostprocessor.inishregistration()中记录的。

if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) {
    Assert.state(this.beanFactory != null, "BeanFactory must be set to find scheduler by type");
    try {
        // Search for TaskScheduler bean...
        this.registrar.setTaskScheduler(this.beanFactory.getBean(TaskScheduler.class));
    }
    catch (NoSuchBeanDefinitionException ex) {
        logger.debug("Could not find default TaskScheduler bean", ex);
        // Search for ScheduledExecutorService bean next...
        try {
            this.registrar.setScheduler(this.beanFactory.getBean(ScheduledExecutorService.class));
        }
        catch (NoSuchBeanDefinitionException ex2) {
            logger.debug("Could not find default ScheduledExecutorService bean", ex);
            // Giving up -> falling back to default scheduler within the registrar...
        }
    }
}

This process attempts to set the task scheduler for the registrar. For this, it tries to find a registered scheduler bean through BeanFactory.getBean method:

此过程试图为注册者设置任务调度器。为此,它尝试通过BeanFactory查找一个已注册的调度器bean。getBean方法:

  1. Tries to find a configured TaskScheduler bean, if not found then fallbacks to->
  2. 尝试找到一个已配置的TaskScheduler bean,如果没有找到,则返回->。
  3. finding ScheduledExecutorService bean, if not found then fallbacks to->
  4. 找到ScheduledExecutorService bean,如果没有找到,则返回->。
  5. using the default scheduler within the registrar (The same is indicated in the code comment above: // Giving up -> falling back to default scheduler within the registrar...)
  6. 使用registrar内的默认调度器(在上面的代码注释中表示://放弃->返回到注册中心的默认调度器…)

If any of the TaskScheduler or ScheduledExecutorService bean is not found in the container, BeanFactory.getBean throws an exception.

如果在容器中没有发现TaskScheduler或ScheduledExecutorService bean,那么BeanFactory。getBean将抛出一个异常。

ScheduledAnnotationBeanPostProcessor in turn logs these exception with DEBUG level:

ScheduledAnnotationBeanPostProcessor将这些异常记录到DEBUG级别:

logger.debug("Could not find default TaskScheduler bean", ex);
logger.debug("Could not find default ScheduledExecutorService bean", ex);

So, in conclusion these exceptions are just logged in process of finding a fallback option for task scheduler bean, and they do not affect the execution of the application.

因此,在结论中,这些异常只是在为任务调度程序bean找到一个回退选项的过程中记录下来的,而且它们不会影响应用程序的执行。

The log level of this class can be elevated so that these DEBUG level messages are not logged like so:

这个类的日志级别可以被提升,这样这些调试级别的消息就不会被记录下来:

<!-- Elevate the log level for 'org.springframework.scheduling' since in
     process of registering the scheduled task, Spring's
     ScheduledAnnotationBeanPostProcessor tries to find TaskScheduler and
     ScheduledExecutorService beans and then fallbacks to its internal
     scheduler but in the process logs exceptions when it cannot find those
     beans registered.
-->
<logger name="org.springframework.scheduling">
    <level value="info" />
</logger>

#2


-1  

Annote your MobileNotifSchedulerBean with @Configurable. I think it will work.

请注意您的mobilenotifschedule erbean与@可配置。我想这行得通。