1
votes

Impossible d'utiliser @Async dans Spring Boot

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 commentaires

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 () depuis public Executor getAsyncExecutor () soit nommer votre bean comme "taskExecutor" par exemple @Bean (name = "taskExecutor") public Executor getAsyncExecutor ()


3 Réponses :


0
votes

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


0 commentaires

0
votes

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 .


1 commentaires

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.



0
votes

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 .


1 commentaires

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.