Не могу использовать @Async при весенней загрузке - PullRequest
0 голосов
/ 14 января 2019

Я хочу использовать асинхронный механизм весенней загрузки, вот мой код.

@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();
        };
    }

}

И я добавляю аннотацию @Async к методу другого класса.

@Override
public Future<Result> getResult(String name); 

Но когда я вызываю метод getResult(), он сообщает No bean named 'taskExecutor' available: No matching Executor bean found for qualifier 'taskExecutor' - neither qualifier match nor bean name match!.

А потом я нахожу эту страницу: https://www.baeldung.com/spring-async. Я следую инструкциям этой страницы - удалите аннотацию @EnableAsync на Application.class и добавьте к AsyncConfig.class. Но все равно получено то же сообщение об ошибке. Кажется, что метод setBeanName() не действует. Мое использование неправильно?

Кстати, я прочитал api doc EnableAsync, там написано

Примечание. В приведенном выше примере {@code ThreadPoolTaskExecutor} не является полностью управляемым компонентом Spring. Добавьте аннотацию {@code @Bean} в метод {@code getAsyncExecutor ()}

если вы хотите полностью управляемый компонент. В таких обстоятельствах больше нет необходимости вручную вызовите метод {@code executor.initialize ()}, так как он будет вызван автоматически при инициализации компонента.

Что означает not a fully managed Spring bean? Какая часть боба не управляется Spring?

Ответы [ 3 ]

0 голосов
/ 14 января 2019

Хотя в спецификации JavaBeans используется get (или is) с префиксом к имени свойства для метода-получателя, методы Spring @Bean не используют это соглашение о «переводе». Имя вашего бина-исполнителя буквально getAsyncExecutor; переименуйте его в taskExecutor.

0 голосов
/ 14 января 2019

Похоже, что ваш Application не является классом конфигурации.

Поместите @EnableAsync в класс, который имеет @SpringBootApplciation или для класса, помеченного @Configuration.

0 голосов
/ 14 января 2019

Добавьте имя к аннотации bean-компонента, например @Bean(name="taskExecutor"). Это должно сделать ваш бин доступным под именем taskExecutor. По умолчанию регистрируется bean-компонент с именем methodName . Смотрите здесь для справки Спринг Бин

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...