#spring #spring-annotations #spring-async
#spring #spring-аннотации #spring-асинхронный
Вопрос:
В компоненте spring у меня есть этот метод:
@Async("@taskExecutorFactory.getOrCreate(#taskId)")
public void updateTask(String taskId) {
// update code
}
Я хотел бы использовать другого исполнителя для каждого вызова. Исполнитель предоставляется TaskExecutorFactory
компонентом в соответствии с taskId
.
Выражение @taskExecutorFactory.getOrCreate(#taskId)
не распознается spring при запуске с ошибкой:
A component required a bean named '@taskExecutorFactory.getOrCreate(#chainTaskId)'
that could not be found.
Есть идеи, возможно ли это?
Комментарии:
1. Потому что это не перенос выражения SpEL
#{...}
, хотя это все еще не гарантирует, что оно будет работать. Зачем вам нужен другой исполнитель для каждого вызова? У исполнителя должен быть пул потоков, которые обрабатывают работу, зачем усложнять ее, добавляя несколько исполнителей.2. Я уже пытался обернуть его,
#{...}
но это не сработало. Я использую отдельных исполнителей, потому что мне нужно убедиться, что обновление выполняется только один раз, даже если мы получаем два запроса одновременно. Для этого я использую исполнителя с ограниченной очередью размером 1.3. Но использование разных исполнителей заставляет их выполняться параллельно, и вы не обновляете один раз. Кроме того, размер очереди, равный единице, не препятствует этому, он помещает вещи в очередь только тогда, когда она не обрабатывается (т. Е. Все потоки в пуле заняты). Похоже, вы пытаетесь что-то решить с помощью многопоточности, которую вы должны решить по-другому.
4. Возможно, для этого есть лучшее решение (мне интересно), но то, что я делаю прямо сейчас, похоже, работает. У меня разные задачи, которые мне нужно обновлять независимо. Когда я получаю запрос на обновление задачи в первый раз, я создаю нового исполнителя, который будет обрабатывать все будущие запросы на обновление для этой же задачи, и удаляю его, как только мы закончим с этой задачей. Если я получаю N запросов одновременно для одной задачи, мне нужно обработать только один из них, поэтому я использую один поток с очередью размером 1.