Это левиОса, а не левиоса!

В части 1 я рассмотрел основной принцип АОП и то, как Spring реализует АОП во время выполнения, а также некоторые неправильные представления о том, как это работает. Теперь давайте рассмотрим простой пример реализации Spring AOP.

Класс аспекта

Так выглядит аспектный класс. Мы сосредоточимся на трех вещах:

  1. Первое, на что следует обратить внимание, — это аннотация @Aspect. Spring поместит экземпляр этого класса в контекст приложения и сделает все за вас (конвенция важнее конфигурации, ура!).
  2. Аннотация @Poincut над пустым методом кажется немного странной, но на самом деле это так. Мы сосредоточимся на этом позже.
  3. Совет тот, что с аннотацией @Before. Есть некоторые другие аннотации, зависящие от того, где ваш совет влияет на точку соединения. Мы сосредоточимся на этом позже.

Точечная резка

Как я объяснял ранее в части 1, pointcut в Spring AOP определяет вызовы методов, на которые повлияет Aspect. Его внешний вид может быть немного странным, так как это в основном пустой метод, аннотированный какими-то выражениями внутри. Давайте посмотрим поближе, не так ли?

Обозначение Pointcut определяет элементы в сигнатуре метода, которые будут проверены, в этом случае я использую execution. Внутри мы можем определить, выполнение какого метода будет связано с советом. В этом случае это повлияет на любой метод с: любым методом внутри класса ServiceTarget внутри пакета com.mokapos.demo.spring.aop.*anything* с любым типом возвращаемого значения.

В Spring AOP можно использовать восемь указателей pointcut: выполнение, внутри, это, цель, args, @target, @args, @within, @annotation. Вы можете прочитать документацию здесь: https://docs.spring.io/spring/docs/2.0.x/reference/aop.html#aop-ataspectj-advice-ordering

Совет Метод

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

В этом простом случае у нас есть совет, который будет выполняться перед выполнением затронутых методов (точек соединения). Внутри мы просто хотим поместить сообщение журнала. Мы должны связать совет с желаемым pointcut (ами), поместив вызов метода pointcut внутри аннотации совета: @Before("voidPointcut()").

Есть пять советов, которые мы можем использовать в Spring AOP:

  1. Before : запустить перед выполнением точки соединения
  2. AfterReturning : запуск после успешного выполнения точки соединения без исключения.
  3. AfterThrowing : запуститься после того, как точка соединения будет выполнена с выброшенным исключением.
  4. After : выполняется после выполнения точки соединения независимо от статуса (нормальный или с исключением), более или менее похоже на finally в операторе try-catch.
  5. Around : самый мощный совет, он окружает выполнение точки соединения и может изменять значения параметров и возвращаемое значение точки соединения.

Реализация услуги

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

voidExecution соответствует pointcut, который мы определили ранее, надеюсь, он будет сплетен Spring AOP. Для того, чтобы убедиться, что это работает, нам нужно одно:

Модульный тест

Теперь давайте попробуем наш аспект, создав модульный тест.

Основной поток этого модульного теста — создание двух экземпляров ServiceTarget — службы с методом, который будет переплетен с нашим аспектом. Первый экземпляр — serviceTarget, базовый экземпляр службы. Второй экземпляр — serviceTargetProxy, прокси-объект ServiceTarget.

Мы создаем serviceTargetProxy вручную, используя AspectJProxyFactory. Целью фабрики является соединение экземпляра службы с требуемым экземпляром аспекта, в данном случае executionAspect.

Теперь мы запускаем прокси-объект и смотрим, работает ли наш аспект так, как задумано.

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

Несколько советов для вас

Не каламбур.

  1. Не усложняйте. Некоторые из нас могут переусердствовать, накладывая несколько аспектов друг на друга. Не надо. АОП берет определенную логику и откладывает ее, скрывая озабоченность. Очевидно, это еще один уровень беспокойства, а сложные аспекты без документации — еще один путь к катастрофе.
  2. Помните, что он ДОЛЖЕН сокращать выполнение нескольких методов: когда он используется только для одного метода в классе службы, это не аспект, а бизнес-процесс, и вместо этого он должен быть частью тела метода службы.
  3. Проведите модульное тестирование. Есть способ убедиться, что наш pointcut работает, — модульное тестирование.
  4. Не бойтесь . Иногда это может вызывать головную боль, но когда вы можете уловить концепцию и реализовать ее достаточно часто, на самом деле это не так уж и страшно.

Эта история только поверхностно описывает Spring AOP, но я надеюсь, что она придаст вам достаточно уверенности, чтобы попробовать. Всем удачного кодирования.