Углубленное понимание 8 основных ошибок аннотации @Async в Spring Boot.
Углубленное понимание 8 основных ошибок аннотации @Async в Spring Boot.
🎉Углубленное понимание 8 основных ошибок аннотации @Async в Spring Boot.

Spring Boot — это популярная среда разработки Java, предоставляющая богатый набор функций и удобную настройку, позволяющую разработчикам больше сосредоточиться на бизнес-логике. Что касается асинхронного программирования, Spring Bootпредоставил@Asyncаннотация,Это позволяет выполнить метод асинхронно.,Улучшите производительность параллельной работы системы. Однако,в использовании@Asyncаннотациячас,Есть некоторые потенциальные подводные камни, о которых следует знать。В этой статье будет подробно рассмотреноSpring Bootиспользуется в@Asyncаннотациячасможет столкнутьсяиз8большие ловушки,и предложить соответствующие решения.

1. Отсутствует аннотация @EnableAsync.

в использовании@Asyncаннотация До,Должно быть весной BootВ основной класс конфигурации приложения добавьте@EnableAsyncаннотация,чтобы включить поддержку асинхронного метода. Если вы проигнорируете этот шаг,@Asyncаннотацияне вступит в силу。

Язык кода:javascript
копировать
@SpringBootApplication
@EnableAsync
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

2. Асинхронные методы должны быть независимыми

одеяло@Asyncаннотация Изменитьизметодне может быть напрямуюодеялотот же класссерединаиздругойметодвызов。потому чтоSpringбудет работатьчас Создать прокси-класс,При вызове асинхронного метода вы фактически вызываете метод этого прокси-класса. поэтому,Если вы вызываете асинхронный метод непосредственно в том же классе,@Asyncаннотацияне вступит в силу。

Язык кода:javascript
копировать
@Service
public class YourService {
    @Async
    public void asyncMethod() {
        // асинхронная логика выполнения
    }

    public void callingAsyncMethod() {
        // Прямой вызов asyncMethod не будет выполнен.
        asyncMethod();
    }
}

Решение состоит в том, чтобы ввести инъекциюYourServiceпрокси-объект для вызоваасинхронныйметод。

Язык кода:javascript
копировать
@Service
public class YourService {
    @Autowired
    private YourService self;

    @Async
    public void asyncMethod() {
        // асинхронная логика выполнения
    }

    public void callingAsyncMethod() {
        // Вызов асинхронного метода через прокси-объект
        self.asyncMethod();
    }
}

3. Разные асинхронные методы не могут вызывать друг друга

Если в том же классе асинхронный метод вызывает другой асинхронный метод, также возникнет проблема с асинхронным выполнением. Это связано с тем, что Spring использует AOP на основе прокси-сервера для реализации асинхронных методов по умолчанию, а вызовы методов внутри прокси-объекта не запускают перехват AOP.

Язык кода:javascript
копировать
@Service
public class YourService {
    @Async
    public void asyncMethod1() {
        // асинхронная логика выполнения
    }

    @Async
    public void asyncMethod2() {
        // асинхронная логика выполнения
        asyncMethod1(); // Этот вызов не будет выполнен
    }
}

Решение состоит в том, чтобы получить текущий прокси-объект через AopContext.currentProxy() и затем вызвать асинхронный метод.

Язык кода:javascript
копировать
@Service
public class YourService {
    @Autowired
    private YourService self;

    @Async
    public void asyncMethod1() {
        // асинхронная логика выполнения
    }

    @Async
    public void asyncMethod2() {
        // асинхронная логика выполнения
        self.asyncMethod1(); // Выполнить асинхронно через вызов прокси-объекта
    }
}

4. Асинхронные методы с возвращаемыми значениями void не могут перехватывать исключения

Если вы используете@Asyncаннотацияизасинхронныйметодиз Возвращаемое значениеvoid,Тогда исключение, созданное в этом методе, не будет перехвачено. Это связано с тем, что исключения не могут передаваться между потоком, вызывающим асинхронный метод, и потоком, который фактически выполняет асинхронный метод.

Язык кода:javascript
копировать
@Service
public class YourService {
    @Async
    public void asyncMethod() {
        // асинхронная логика выполнения
        throw new RuntimeException("Async method exception");
    }
}

Решение состоит в том, чтобы установить возвращаемое значениеFuture,Таким образом вы можете позвонитьget()методчас Исключение поймано。

Язык кода:javascript
копировать
@Service
public class YourService {
    @Async
    public Future<Void> asyncMethod() {
        // асинхронная логика выполнения
        throw new RuntimeException("Async method exception");
    }
}

При вызове асинхронного метода,может пройтиFutureизget()метод Исключение поймано。

Язык кода:javascript
копировать
@Service
public class YourService {
    @Autowired
    private YourService self;

    public void callAsyncMethod() {
        try {
            self.asyncMethod().get();
        } catch (Exception e) {
            // поймать исключение
        }
    }
}

5. Методы, помеченные @Async, нельзя вызывать напрямую извне.

Если вызывается непосредственно в том же классе с@Asyncаннотацияизметод,Оно не может быть выполнено. Потому что Spring сгенерирует прокси-класс во время выполнения.,Внешние прямые вызовы фактически вызывают методы исходного класса.,Вместо метода прокси-класса.

Язык кода:javascript
копировать
@Service
public class YourService {
    @Async
    public void asyncMethod() {
        // асинхронная логика выполнения
    }
}

@Service
public class AnotherService {
    @Autowired
    private YourService yourService;

    public void callAsyncMethod() {
        // внешний Прямой вызов asyncMethod не будет выполнен.
        yourService.asyncMethod();
    }
}

Решение состоит в том, чтобы ввести инъекциюYourServiceпрокси-объект для вызоваасинхронныйметод。

Язык кода:javascript
копировать
@Service
public class YourService {
    @Autowired
    private YourService self;

    @Async
    public void asyncMethod() {
        // асинхронная логика выполнения
    }
}

@Service
public class AnotherService {
    @Autowired
    private YourService self;

    public void callAsyncMethod() {
        // Вызов асинхронного метода через прокси-объект
        self.asyncMethod();
    }
}

6. Метод @Async не работает с частным методом.

@Asyncаннотация Только публичнометодэффективный,Поэтому «частное

Метод не может быть выполнен. Если попытаться датьprivateМетод добавлен@Async`аннотация,не будет иметь никакого эффекта.

Язык кода:javascript
копировать
@Service
public class YourService {
    @Async
    private void asyncMethod() {
        // @Asyncannotation здесь не вступит в силу
    }
}

Решение состоит в том, чтобы извлечь логику, которая будет выполняться асинхронно, в общедоступный метод и вызвать этот общедоступный метод в частном методе.

Язык кода:javascript
копировать
@Service
public class YourService {
    @Async
    public void asyncMethod() {
        doAsyncMethod();
    }

    private void doAsyncMethod() {
        // асинхронная логика выполнения
    }
}

7. Отсутствует конфигурация пула асинхронных потоков.

в использовании@Asyncаннотациячас,Spring Boot по умолчанию создаст пул потоков для выполнения асинхронного метода. Если не настроено,по умолчаниюиспользоватьиздаSimpleAsyncTaskExecutor,Это однопоточный исполнитель,Может вызвать узкие места в производительности.

Чтобы решить эту проблему, можно настроить подходящий пул потоков. Вот пример конфигурации:

Язык кода:javascript
копировать
@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        return executor;
    }
}

Эта конфигурация используетThreadPoolTaskExecutor,И установите такие параметры, как количество основных потоков, максимальное количество потоков и емкость очереди.,Внесите коррективы в соответствии с реальными условиями.

8. Совместимость асинхронных методов и транзакций

по умолчанию,использовать@Asyncаннотацияизметод与делада不兼容из。потому чтов использованииделаизметодсерединавызовиспользовать@Asyncаннотацияизметодчас,Транзакции не будут распространяться на асинхронные методы.,Асинхронный метод будет выполнен без транзакции.

Решение состоит в том, чтобы@Asyncаннотация Добавить в другой классизметодначальство,Асинхронный метод вызывается через прокси-объект.

Язык кода:javascript
копировать
@Service
public class YourService {
    @Autowired
    private AsyncService asyncService;

    @Transactional
    public void transactionalMethod() {
        // Вызов асинхронного метода в транзакции
        asyncService.asyncMethod();
    }
}

@Service
public class AsyncService {
    @Async
    public void asyncMethod() {
        // асинхронная логика выполнения
    }
}

Переместив асинхронный метод в другой класс, вы можете гарантировать, что асинхронный метод будет выполняться в новой транзакции и не будет конфликтовать с внешними транзакциями.

Заключение

использовать@Asyncаннотациявозможность улучшить системуиз Производительность параллелизма,нов использованиичас Необходимо знать о некоторых возможностяхизвопрос。проходить Узнайте больше о весне Bootсередина@Asyncаннотацияизэтот8большие ловушки,и принять соответствующие решения,Может лучше применять асинхронное программирование,Обеспечить надежность и производительность системы. Надеюсь, эта статья поможет вам понять и использовать Spring Асинхронная аннотация в Boot.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose