Главная » Spring » Объявление асинхронных методов Spring

0

Производительность приложения может оцениваться как фак- тическая и воспринимаемая человеком. Безусловно, фактическая производительность приложения (определяется временем, необ- ходимым на выполнение операций) играет важную роль. Но даже когда фактическая производительность далека от идеала, этот не- достаток отчасти можно замаскировать за воспринимаемой произ- водительностью.

Воспринимаемая производительность – это именно то, что озна- чает ее название. Кому интересно знать, как долго выполняется та или иная операция, если по мнению пользователя приложение от- кликается на его действия немедленно? Например, допустим, что добавление нового сообщения является достаточно продолжитель- ной операцией. При синхронном ее выполнении воспринимаемая производительность будет прямо пропорциональна фактической производительности. Пользователь будет вынужден ждать, пока приложение будет сохранено на сервере.

Но если появится возможность выполнять метод saveSpittle() класса SpitterService асинхронно, тогда приложение сможет пред- ставить пользователю новую страницу, пока логика сохранения бу- дет выполняться в фоновом режиме. Именно эту цель преследует аннотация @Async.

@Async – это простая аннотация, не имеющая атрибутов. Достаточ- но просто отметить метод компонента этой аннотацией, и он пре- вратится в асинхронный метод. Сложно придумать что-либо более простое.

Например, ниже показано, как можно превратить метод save- Spittle() класса SpittleServiceImpl в асинхронный метод:

@Async

public  void  addSpittle(Spittle  spittle)  {

}

Этого действительно достаточно. Когда приложение вызовет метод saveSpittle(), управление немедленно будет возвращено вы- зывающей программе. При этом сам метод saveSpittle() продолжит выполнение в фоновом режиме.

У вас может возникнуть вопрос: а что, если асинхронный метод возвращает некоторое значение? Если управление будет возвращено немедленно, как тогда он сможет вернуть результаты?

Так как асинхронные методы в Spring основаны на API парал- лельного выполнения, они могут возвращать объект, реализующий интерфейс java.util.concurrent.Future. Этот интерфейс представляет хранилище для некоторого значения, которое будет доступно спустя некоторое время после возврата из метода, но необязательно в точке вызова этого метода. В состав Spring входит класс AsyncResult, реа- лизующий интерфейс Future и упрощающий работу со значениями, которые будут доступны в будущем.

Например, допустим, что имеется асинхронный метод, выполняю- щий сложные и длительные вычисления. Этот метод желательно было бы выполнять в фоновом режиме, но иметь возможность полу- чать результаты сразу по его завершении. В подобном случае метод можно было объявить, как показано ниже:

@Async

public Future<Long> performSomeReallyHairyMath(long input) {

// …

return  new  AsyncResult<Long>(result);

}

Пока этот метод выполняет длительные вычисления, вызываю- щая программа может продолжать заниматься другими делами. В результате вызова метода программа получит объект Future (фак- тически экземпляр класса AsyncResult), куда будет записан результат по окончании вычислений.

Когда результат будет готов, вызывающая программа сможет из- влечь его вызовом метода get() объекта Future. А до тех пор про- грамма может проверять готовность результата вызовами методов isDone()   и  isCancelled().

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии