Понятия
Модель срезов из Spring позволяет повторно использовать срезы независимо от типов советов. Можно ориентировать разные типы советов с помощью одного и того же среза.
Интерфейс org.springframework.aop.Pointcut
является центральным интерфейсом, используемым для ориентирования советов на определенные классы и методы. Ниже приведен полный интерфейс:
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
}
Разделение интерфейса Pointcut
на две части позволяет повторно использовать части сопоставляемых классов и методов, а также производить тонкие операции компонования (например, выполнять "объединение" с другим средством сопоставления методов (method matcher)).
Интерфейс ClassFilter
используется для ограничения среза заданным набором целевых классов. Если метод matches()
всегда возвращает true, то совпадают все целевые классы. В следующем листинге показано определение интерфейса ClassFilter
:
public interface ClassFilter {
boolean matches(Class clazz);
}
Интерфейс MethodMatcher
обычно более важен. Ниже приведен полный интерфейс:
public interface MethodMatcher {
boolean matches(Method m, Class<?> targetClass);
boolean isRuntime();
boolean matches(Method m, Class<?> targetClass, Object... args);
}
Метод matches(Method, Class)
используется для того, чтобы проверить, соответствует ли данный срез данному методу в целевом классе. Это вычисление может быть выполнено при создании прокси АОП, чтобы избежать необходимости проведения проверки при каждом вызове метода. Если метод matches
с двумя аргументами возвращает true
для данного метода, а метод isRuntime()
возвращает true
для MethodMatcher, то метод соответствия с тремя аргументами будет вызван при каждом вызове метода. Это позволяет срезу просматривать аргументы, переданные в вызов метода непосредственно перед началом выполнения целевого совета.
Большинство реализаций MethodMatcher
являются статическими, что означает, что их метод isRuntime()
возвращает false
. В этом случае метод matches
с тремя аргументами никогда не вызывается.
Операции над срезами
Spring поддерживает операции (в частности, объединение и пересечение) над срезами.
Объединение означает методы, которые совпадают с любым из срезов. Пересечение означает методы, которые совпадают с обоими срезами. Объединение обычно более практичная операция. Вы можете компоновать срезы с помощью статических методов класса org.springframework.aop.support.Pointcuts
или с помощью класса ComposablePointcut
из того же пакета. Однако использование выражений срезов из AspectJ обычно является более простым подходом.
Срезы выражений AspectJ
Начиная с версии 2.0, наиболее важным типом среза, используемым Spring, является org.springframework.aop.aspectj.AspectJExpressionPointcut
. Это срез, который использует библиотеку, поставляемую AspectJ, для синтаксического анализа строки выражения среза из AspectJ.
Обсуждение поддерживаемых срезов-примитивов из AspectJ см. в предыдущей главе.
Удобные реализации срезов
Spring предоставляет несколько удобных реализаций срезов. Некоторые из них можно использовать напрямую; другие предназначены для построения подклассов в специфических для приложения срезах.
Статические срезы
Статические срезы основаны на методе и целевом классе и не могут учитывать аргументы метода. Для большинства случаев использования достаточно статических срезов - и они лучше всего. Spring может вычислить статический срез только один раз, если метод вызывается впервые. После этого нет необходимости повторно вычислять срез при каждом вызове метода.
В остальной части этого раздела описаны некоторые реализации статических срезов, которые включены в Spring.
Срезы регулярных выражений
Одним из очевидных способов задания статических срезов являются регулярные выражения. Несколько АОП-фреймворков, помимо Spring, позволяют осуществлять это. org.springframework.aop.support.JdkRegexpMethodPointcut
– это общий срез регулярного выражения, который использует поддержку регулярных выражений в JDK.
С помощью класса JdkRegexpMethodPointcut
можно указать список строк шаблонов. Если любая из них совпадет, то срез примет значение true
. (Как следствие, результирующий срез фактически будет объединением указанных шаблонов).
В следующем примере показано, как использовать
<bean id="settersAndAbsquatulatePointcut"
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns">
<list>
<value>.*set.*</value>
<value>.*absquatulate</value>
</list>
</property>
</bean>
Spring предоставляет удобный класс RegexpMethodPointcutAdvisor
, который позволяет также ссылаться на Advice
(помните, что Advice
может быть советом "перехват", советом "перед", советом "генерация исключения" и другими). За кулисами Spring использует JdkRegexpMethodPointcut
. Использование RegexpMethodPointcutAdvisor
упрощает связывание, так как один боб инкапсулирует и срез, и совет, как показано в следующем примере:
<bean id="settersAndAbsquatulateAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="beanNameOfAopAllianceInterceptor"/>
</property>
<property name="patterns">
<list>
<value>.*set.*</value>
<value>.*absquatulate</value>
</list>
</property>
</bean>
Вы можете использовать RegexpMethodPointcutAdvisor
с любым типом Advice
.
Срезы, управляемые атрибутами
Важным типом статического среза является срез, управляемый метаданными. При этом используются значения атрибутов метаданных (как правило, метаданных на уровне источника).
Динамические срезы
Вычисление динамических срезов более ресурсоемкая задача. Эти срезы учитывают аргументы метода, а также статическую информацию. Это означает, что их вычисление необходимо производить при каждом вызове метода и что результат нельзя кэшировать, так как аргументы будут меняться.
Основным примером является срез control flow
.
Срезы потока управления
Срезы потока управления (control flow pointcuts) из Spring концептуально похожи на срезы cflow
из AspectJ, хотя и не столь эффективные. (В настоящее время не существует способа, позволяющего задать, чтоб срез проходил ниже точки соединения, совпадающей с другим срезом.) Срез потока управления совпадает с текущим стеком вызовов. Например, он может сработать, если точка соединения была вызвана методом из пакета com.mycompany.web
или классом SomeCaller
. Срезы потока управления задаются с помощью класса org.springframework.aop.support.ControlFlowPointcut
.
Суперклассы срезов
Spring предоставляет практичные суперклассы (родительские классы) срезов, которые могут помочь реализовать ваши собственные срезы.
class TestStaticPointcut extends StaticMethodMatcherPointcut {
public boolean matches(Method m, Class targetClass) {
// возвращает true, если специально заданные критерии совпадают
}
}
class TestStaticPointcut : StaticMethodMatcherPointcut() {
override fun matches(method: Method, targetClass: Class<*>): Boolean {
// возвращает true, если специально заданные критерии совпадают
}
}
Существуют также суперклассы для динамических срезов. Вы можете использовать специальные срезы с любым типом советов.
Специальные срезы
Поскольку срезы в Spring AOP являются классами Java, а не функциями языка (как в AspectJ), вы можете объявлять специальные срезы, как статические, так и динамические. Специальные срезы в Spring могут быть произвольно сложными. Однако рекомендуется использовать язык выражений срезов AspectJ, если это возможно.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ