Affects: 5.2.0
When I use @Bean annotation to create a thread pool(ThreadPoolTaskExecutor) in my project, the thread pool will be created repeatedly if I use Initialize() at the same time. Code is shown below:
@Bean("myThreadPool")
public ThreadPoolTaskExecutor getTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setKeepAliveSeconds(300);
taskExecutor.setAllowCoreThreadTimeOut(true);
taskExecutor.setAwaitTerminationSeconds(60);
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.setThreadNamePrefix("my-thread-pool-");
taskExecutor.setCorePoolSize(8);
taskExecutor.setMaxPoolSize(16);
taskExecutor.setQueueCapacity(100);
taskExecutor.initialize();
return taskExecutor;
}
then I use this function in my service:
public class myService{
@Autowired
@Qualifier("myThreadPool")
private ThreadPoolTaskExecutor taskExecutor;
}
When the program start, the executor(thread pool) will be created twice. The log is : Initializing ExecutorService Initializing ExecutorService 'myThreadPool'
The reason is that I call initizlize() in function getTaskExecutor and a thread pool will be created. After that, Bean 'myThreadPool' injects into myService, and function afterPropertiesSet() in class ThreadPoolTaskExecutor also call initizlize(). So the second thread pool will be created. I want to know whether this condition is reasonable. What is the design idea of calling initizlize() in function afterPropertiesSet()? Or I shouldn't call initialize() in this case?
Code in Spring: https://github.com/spring-projects/spring-framework/blob/4a9c7e631c60a12f3426d42143e9e27be0bf68ab/spring-context/src/main/java/org/springframework/scheduling/concurrent/ExecutorConfigurationSupport.java#L172-L187 In line 182 in function initialize(), I think it is more appropriately to verify that whether this.executor is null before calling initializeExecutor()
Comment From: sbrannen
Hi @tk1996amaranth,
Congratulations on opening your first GitHub issue ever!
What is the design idea of calling initizlize() in function afterPropertiesSet()?
afterPropertiesSet()
comes from the InitializingBean
interface, whose Javadoc states the following.
Interface to be implemented by beans that need to react once all their properties have been set by a
BeanFactory
: e.g. to perform custom initialization, or merely to check that all mandatory properties have been set.
Thus, calling initialize()
from afterPropertiesSet()
ensures that all properties have been set, including the beanName
via the BeanNameAware
interface.
The first log statement does not include the bean name, because the instance has not been fully configured before you invoke initialize()
.
Or I shouldn't call initialize() in this case?
That's correct: you should not call initialize()
, since the framework will indirectly do that for you.
As for the "design idea", the InitializingBean
approach to final configuration/initialization originally comes from XML based bean configuration in which it is not possible to invoke the initialize()
method from XML.
In light of that, I am closing this issue.