Je veux utiliser le mécanisme asynchrone de spring boot, voici mon code.
@Override public Future<Result> getResult(String name);
Et j'ajoute l'annotation @Async sur la méthode d'une autre classe.
@Slf4j
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
private static final int MAX_POOL_SIZE = 50;
private static final int CORE_POOL_SIZE = 20;
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setBeanName("taskExecutor");
taskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
taskExecutor.setCorePoolSize(CORE_POOL_SIZE);
taskExecutor.setThreadNamePrefix("async-task-thread-pool");
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
taskExecutor.setAwaitTerminationSeconds(60 * 10);
taskExecutor.setRejectedExecutionHandler(
(r, executor) -> log.warn("current thread pool is full, reject to invoke."));
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (ex, method, params) ->
{
log.error("invoke async method occurs error. method: {}, params: {}",
method.getName(), JSON.toJSONString(params), ex);
throw new RuntimeException();
};
}
}
3 Réponses :
Ajoutez un nom à votre annotation de bean, comme @Bean (name = "taskExecutor") . Cela devrait rendre votre bean disponible sous le nom taskExecutor. Par défaut, il enregistre un bean avec le nom methodName . Voir ici pour référence Haricot de printemps
Alors que la spécification JavaBeans utilise get (ou est ) préfixé au nom d'une propriété pour la méthode getter, les méthodes Spring @Bean n'utilisez pas cette convention de «traduction». Le nom de votre bean exécuteur est littéralement getAsyncExecutor ; renommez-le en taskExecutor .
J'ai fait qu'AsyncConfigurer implémente l'interface ApplicationContextAware. Et utilisez Object getAsyncExecutor = applicationContext.getBean ("getAsyncExecutor"); dans la méthode setApplicationContext , mais n'obtenez aucun bean nommé d'exception getAsyncExecutor. Et quand j'ai changé pour utiliser String [] beanNamesForType = applicationContext.getBeanNamesForType (Executor.class); mais j'ai trouvé que le beanNamesForType est vide.
Il semble que votre Application ne soit pas une classe de configuration.
Placez le @EnableAsync soit sur la classe qui a le
@SpringBootApplciation ou sur une classe annotée avec @Configuration .
J'ai changé mon code en me référant à docs.spring.io/spring-framework/docs/5.1.4.RELEASE/javadoc-a pi /… . J'ai modifié ma question et mon code, mais ne fonctionne toujours pas.
Voulez-vous publier votre dépôt source?
Désolé, le code n'est pas autorisé à exposer.
Vous devez soit changer le nom de la méthode qui enregistre le bean comme
public Executor taskExecutor ()depuispublic Executor getAsyncExecutor ()soit nommer votre bean comme "taskExecutor" par exemple@Bean (name = "taskExecutor") public Executor getAsyncExecutor ()