1. Введение
В этом руководстве мы познакомимся с АОП (аспектно-ориентированным программированием) с помощью Spring и узнаем, как мы можем использовать этот мощный инструмент в практических сценариях.
Также можно использовать аннотации AspectJ при разработке с помощью Spring AOP, но в этой статье мы сосредоточимся на базовой конфигурации Spring AOP на основе XML.
2. Обзор
АОП — это парадигма программирования, направленная на увеличение модульности за счет разделения сквозных задач. Он делает это, добавляя дополнительное поведение к существующему коду, не изменяя сам код.
Вместо этого мы можем объявить новый код и новое поведение отдельно.
Фреймворк АОП Spring помогает нам реализовать эти сквозные задачи.
3. Зависимости Maven
Начнем с добавления зависимости библиотеки Spring AOP в pom.xml
:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
Последнюю версию зависимости можно проверить здесь .
4. Концепции и терминология АОП
Кратко рассмотрим понятия и терминологию, характерные для АОП:
4.1. Бизнес-объект
Бизнес-объект — это обычный класс с обычной бизнес-логикой. Давайте рассмотрим простой пример бизнес-объекта, где мы просто добавляем два числа:
public class SampleAdder {
public int add(int a, int b) {
return a + b;
}
}
Обратите внимание, что этот класс является обычным классом с бизнес-логикой без каких-либо аннотаций, связанных со Spring.
4.2. Аспект
Аспект — это модульность проблемы, которая охватывает несколько классов. Унифицированное ведение журналов может быть примером такой сквозной проблемы.
Давайте посмотрим, как мы определяем простой Аспект:
public class AdderAfterReturnAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
public void afterReturn(Object returnValue) throws Throwable {
logger.info("value return was {}", returnValue);
}
}
В приведенном выше примере мы определили простой класс Java с методом afterReturn,
который принимает один аргумент типа Object
и регистрирует это значение. Обратите внимание, что даже наш AdderAfterReturnAspect
является стандартным классом, свободным от каких-либо аннотаций Spring.
В следующих разделах мы увидим, как мы можем связать этот аспект с нашим бизнес-объектом.
4.3. Точка присоединения
Точка соединения
— это точка во время выполнения программы, например, выполнения метода или обработки исключения.
В Spring AOP JoinPoint
всегда представляет выполнение метода.
4.4. Точечная резка
Pointcut — это
предикат, который помогает сопоставить рекомендации
, применяемые Аспектом
в конкретной точке присоединения
.
Мы часто связываем Advice
с выражением Pointcut
, и оно запускается в любой точке соединения
, соответствующей Pointcut
.
4.5. Совет
Совет
— это действие, предпринимаемое аспектом в определенной точке соединения
. Различные типы советов включают «примерно», «до»
и «после».
В Spring Advice
моделируется как перехватчик, поддерживающий цепочку перехватчиков вокруг точки соединения
.
4.6. Связывание бизнес-объекта и аспекта
Теперь давайте посмотрим, как мы можем связать бизнес-объект с аспектом с рекомендацией после возврата.
Ниже приведен фрагмент конфигурации, который мы бы поместили в стандартную конфигурацию Spring в тег «<beans>»
:
<bean id="sampleAdder" class="org.foreach.logger.SampleAdder" />
<bean id="doAfterReturningAspect"
class="org.foreach.logger.AdderAfterReturnAspect" />
<aop:config>
<aop:aspect id="aspects" ref="doAfterReturningAspect">
<aop:pointcut id="pointCutAfterReturning" expression=
"execution(* org.foreach.logger.SampleAdder+.*(..))"/>
<aop:after-returning method="afterReturn"
returning="returnValue" pointcut-ref="pointCutAfterReturning"/>
</aop:aspect>
</aop:config>
Как мы видим, мы определили простой bean-компонент с именем simpleAdder,
который представляет собой экземпляр бизнес-объекта. Кроме того, мы создали экземпляр Aspect с именем AdderAfterReturnAspect
.
Конечно, XML здесь не единственный вариант; как упоминалось ранее, аннотации AspectJ также полностью поддерживаются.
4.7. Конфигурация с первого взгляда
Мы можем использовать тег aop:config
для определения конфигурации, связанной с АОП. В теге конфигурации
мы определяем класс, представляющий аспект. Затем мы даем ему ссылку на «doAfterReturningAspect»
, созданный нами аспектный компонент.
Затем мы определяем Pointcut, используя тег pointcut .
Pointcut, используемый в приведенном выше примере, — это execute(* org.foreach.logger.SampleAdder+.*(..)),
что означает применение рекомендации к любому методу в классе SampleAdder
, который принимает любое количество аргументов и возвращает любой тип значения.
Затем мы определяем, какой совет мы хотим применить. В приведенном выше примере мы применили совет после возврата. Мы определили это в нашем аспекте AdderAfterReturnAspect
, выполнив метод afterReturn
, который мы определили с помощью метода атрибута.
Этот совет внутри Aspect принимает один параметр типа Object.
Параметр дает нам возможность выполнить действие до и/или после вызова целевого метода. В этом случае мы просто регистрируем возвращаемое методом значение.
Spring AOP поддерживает несколько типов рекомендаций с использованием конфигурации на основе аннотаций. Этот и другие примеры можно найти здесь и здесь .
5. Вывод
В этой статье мы проиллюстрировали концепции, используемые в АОП. Мы также рассмотрели примеры использования АОП-модуля Spring. Если мы хотим узнать больше об АОП, мы можем обратиться к следующим ресурсам:
- Введение в AspectJ
- Реализация пользовательской аннотации Spring AOP
- Введение в выражения Pointcut в Spring
- Сравнение Spring AOP и AspectJ
- Введение в типы советов в Spring
Реализацию этих примеров можно найти на GitHub .