@ -19,7 +19,6 @@ package org.springframework.scheduling.annotation;
import java.lang.reflect.Method ;
import java.lang.reflect.Method ;
import java.lang.reflect.Modifier ;
import java.lang.reflect.Modifier ;
import java.util.Collections ;
import java.util.Collections ;
import java.util.HashMap ;
import java.util.LinkedHashSet ;
import java.util.LinkedHashSet ;
import java.util.Map ;
import java.util.Map ;
import java.util.Set ;
import java.util.Set ;
@ -35,6 +34,8 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware ;
import org.springframework.beans.factory.BeanFactoryAware ;
import org.springframework.beans.factory.DisposableBean ;
import org.springframework.beans.factory.DisposableBean ;
import org.springframework.beans.factory.ListableBeanFactory ;
import org.springframework.beans.factory.ListableBeanFactory ;
import org.springframework.beans.factory.NoSuchBeanDefinitionException ;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException ;
import org.springframework.beans.factory.SmartInitializingSingleton ;
import org.springframework.beans.factory.SmartInitializingSingleton ;
import org.springframework.beans.factory.config.BeanPostProcessor ;
import org.springframework.beans.factory.config.BeanPostProcessor ;
import org.springframework.context.ApplicationContext ;
import org.springframework.context.ApplicationContext ;
@ -87,7 +88,7 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
private StringValueResolver embeddedValueResolver ;
private StringValueResolver embeddedValueResolver ;
private Listable BeanFactory beanFactory ;
private BeanFactory beanFactory ;
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar ( ) ;
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar ( ) ;
@ -121,7 +122,7 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
* /
* /
@Override
@Override
public void setBeanFactory ( BeanFactory beanFactory ) {
public void setBeanFactory ( BeanFactory beanFactory ) {
this . beanFactory = ( beanFactory instanceof ListableBeanFactory ? ( ListableBeanFactory ) beanFactory : null ) ;
this . beanFactory = beanFactory ;
}
}
/ * *
/ * *
@ -141,8 +142,9 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
this . registrar . setScheduler ( this . scheduler ) ;
this . registrar . setScheduler ( this . scheduler ) ;
}
}
if ( this . beanFactory ! = null ) {
if ( this . beanFactory instanceof ListableBeanFactory ) {
Map < String , SchedulingConfigurer > configurers = this . beanFactory . getBeansOfType ( SchedulingConfigurer . class ) ;
Map < String , SchedulingConfigurer > configurers =
( ( ListableBeanFactory ) this . beanFactory ) . getBeansOfType ( SchedulingConfigurer . class ) ;
for ( SchedulingConfigurer configurer : configurers . values ( ) ) {
for ( SchedulingConfigurer configurer : configurers . values ( ) ) {
configurer . configureTasks ( this . registrar ) ;
configurer . configureTasks ( this . registrar ) ;
}
}
@ -150,21 +152,30 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
if ( this . registrar . hasTasks ( ) & & this . registrar . getScheduler ( ) = = null ) {
if ( this . registrar . hasTasks ( ) & & this . registrar . getScheduler ( ) = = null ) {
Assert . state ( this . beanFactory ! = null , "BeanFactory must be set to find scheduler by type" ) ;
Assert . state ( this . beanFactory ! = null , "BeanFactory must be set to find scheduler by type" ) ;
Map < String , ? super Object > schedulers = new HashMap < String , Object > ( ) ;
try {
schedulers . putAll ( this . beanFactory . getBeansOfType ( TaskScheduler . class ) ) ;
// Search for TaskScheduler bean...
schedulers . putAll ( this . beanFactory . getBeansOfType ( ScheduledExecutorService . class ) ) ;
this . registrar . setScheduler ( this . beanFactory . getBean ( TaskScheduler . class ) ) ;
if ( schedulers . size ( ) = = 0 ) {
// do nothing -> fall back to default scheduler
}
}
else if ( schedulers . size ( ) = = 1 ) {
catch ( NoUniqueBeanDefinitionException ex ) {
this . registrar . setScheduler ( schedulers . values ( ) . iterator ( ) . next ( ) ) ;
throw new IllegalStateException ( "More than one TaskScheduler exists within the context. " +
"Remove all but one of the beans; or implement the SchedulingConfigurer interface and call " +
"ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback." , ex ) ;
}
}
else if ( schedulers . size ( ) > = 2 ) {
catch ( NoSuchBeanDefinitionException ex ) {
throw new IllegalStateException ( "More than one TaskScheduler and/or ScheduledExecutorService " +
logger . debug ( "Could not find default TaskScheduler bean" , ex ) ;
"exist within the context. Remove all but one of the beans; or implement the " +
// Search for ScheduledExecutorService bean next...
"SchedulingConfigurer interface and call ScheduledTaskRegistrar#setScheduler " +
try {
"explicitly within the configureTasks() callback. Found the following beans: " +
this . registrar . setScheduler ( this . beanFactory . getBean ( ScheduledExecutorService . class ) ) ;
schedulers . keySet ( ) ) ;
}
catch ( NoUniqueBeanDefinitionException ex2 ) {
throw new IllegalStateException ( "More than one ScheduledExecutorService exists within the context. " +
"Remove all but one of the beans; or implement the SchedulingConfigurer interface and call " +
"ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback." , ex ) ;
}
catch ( NoSuchBeanDefinitionException ex2 ) {
logger . debug ( "Could not find default ScheduledExecutorService bean" , ex ) ;
// Giving up -> falling back to default scheduler within the registrar...
}
}
}
}
}