Spring AOP: в чем разница между JoinPoint и PointCut?


Я изучаю концепции аспектно-ориентированного программирования и Spring AOP. Я не могу понять разницу между Pointcut и Joinpoint - оба они кажутся одинаковыми для меня. В разделительных вы можете применить Ваши советы и Joinpoint также место, где мы можем применить наши советы. Тогда какая разница?

примером pointcut может быть:

@Pointcut("execution(* * getName()")

что может быть примером Joinpoint?

13 69

13 ответов:

Joinpoint: точка соединения-это кандидат точка Выполнение Программы приложения, где аспект может быть подключен. Эта точка может быть вызванным методом, вызванным исключением или даже измененным полем. Это точки, где код вашего аспекта может быть вставлен в обычный поток вашего приложения, чтобы добавить новое поведение.

Совет: это объект, который включает в себя вызовы API к общесистемным проблемам относится представление действия, выполняемого в точке соединения, указанной точкой.

Pointcut: pointcut определяет, в каких точках соединения должны применяться соответствующие рекомендации. Рекомендации могут быть применены в любой точке соединения, поддерживаемой платформой AOP. Конечно, вы не хотите применять все свои аспекты во всех возможных точках соединения. Pointcuts позволяет указать, где вы хотите, чтобы ваш совет был применен. Часто вы указать эти точки, используя явные имена классов и методов или с помощью регулярных выражений, определяющих соответствующие шаблоны имен классов и методов. Некоторые платформы AOP позволяют создавать динамические pointcuts, которые определяют, следует ли применять рекомендации на основе решений среды выполнения, таких как значение параметров метода.

следующее изображение может помочь вам понять советы, PointCut, Joinpoints. enter image description here

источник

объяснение с использованием ресторанной аналогии: источник @Victor

когда вы выходите в ресторан, вы смотрите на меню и видите несколько вариантов на выбор. Вы можете заказать один или несколько пунктов меню. Но пока вы на самом деле не заказываете их, они просто "возможности пообедать". Как только вы делаете заказ и официант приносит его к вашему столу, это еда.

Joinpoints варианты в меню и pointcut являются элементы, которые вы выберите.

точка соединения является возможность в коде для вас применить аспект...просто возможность. Как только вы воспользуетесь этой возможностью и выберете одну или несколько точек соединения и примените к ним аспект, у вас есть Pointcut.

чтобы понять разницу между точкой соединения и pointcut, подумайте о pointcuts как указание правил плетения и точек соединения как ситуаций, удовлетворяющих этим правилам.

в приведенном ниже примере,

  @Pointcut("execution(* * getName()")  

Pointcut определяет правила, говорящие, что совет должен применяться к методу getName (), присутствующему в любом классе в любом пакете, и joinpoints будет списком всех методов getName (), присутствующих в классах, чтобы Совет мог быть применен к этим методам.

(In в случае Spring правило будет применяться только к управляемым бобам, а советы могут применяться только к публичным методам).

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

Pointcuts: Pointcuts-это что-то вроде регулярных выражений, которые используются для идентификации точки соединения. Pontcuts выражаются с помощью "pointcut язык выражений". Pointcuts-это точки потока выполнения, в которых необходимо применять сквозную озабоченность. Существует разница между Joinpoint и Pointcut; Joinpoints являются более общими и представляют собой любой поток управления, где мы "можем выбрать" ввести сквозную проблему, в то время как pointcuts определяет такие точки соединения, где "мы хотим" ввести сквозную проблему.

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

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

class Employee{
    public String getName(int id){....}
    private int getID(String name){...}
}

эти методы называются JoinPoints. Нам нужен способ определить эти методы, чтобы структура могла найти методы, среди всех классов.методы, которые он загрузил. Поэтому мы напишем регулярное выражение, соответствующее сигнатуре этих методов. Хотя это еще не все, как вы увидите ниже, но свободно это регулярное выражение определяет Pointcut. например,

* * mypackage.Employee.get*(*)

первый * предназначен для модификатора public / private / protected / default. Второй * - для возвращаемого типа метода.

но тогда вам также нужно сказать еще два вещи:

  1. , когда должны ли быть приняты меры - например, до / после выполнения метода или при исключении
  2. что должен ли он делать, когда он соответствует (может быть, просто распечатать сообщение)

комбинация этих двух называется советы.

как вы можете себе представить, вам придется написать функцию, чтобы быть в состоянии сделать #2. Так вот как это может выглядеть для основы.

Примечание: Для ясности, используя слово регулярное выражение вместо * * mypackage.Employee.get*(*). В действительности полное выражение входит в определение.

@Before("execution(REGEX)")
public void doBeforeLogging() {....}   <-- executed before the matching-method is called

@After("execution(REGEX)")
public void doAfterLogging() {....}  <-- executed after the matching-method is called

как только вы начнете использовать их совсем немного, вы можете в конечном итоге указать много @After/@Before/@вокруг Советов. Элемент повторное регулярные выражения в конечном итоге в конечном итоге делают вещи запутанными и трудными для поддержания. Итак, что мы делаем, мы просто даем имя выражения и использовать его везде в Класс аспекта.

@Pointcut("execution(REGEX)") <-- Note the introduction of Pointcut keyword
public void allGetterLogging(){} <-- This is usually empty

@Before("allGetterLogging")
public void doBeforeLogging() {....}

@After("allGetterLogging")
public void doAfterLogging() {....}

кстати, вы также хотели бы обернуть всю эту логику в класс, который называется аспект и вы бы написали класс:

@Aspect
public class MyAwesomeAspect{....}

чтобы заставить все эти вещи работать, вам нужно будет сказать Spring, чтобы проанализировать классы, чтобы прочитать, понять и принять меры по ключевым словам @ AOP. Один из способов сделать это-указать следующее в файле xml spring config:

<aop:aspectj-autoproxy>

сравнивая язык AOP, такой как AspectJ, с языком запросов данных, таким как SQL, вы можете думать о joinpoints (т. е. обо всех местах в вашем коде, где вы можете сплести код аспекта) как таблицу базы данных со многими строками. Pointcut похож на SELECT stamement, который может выбрать пользовательское подмножество строк / точек соединения. Фактический код, который вы вплетаете в эти выбранные места, называется советом.

оба относятся к" где " аспектно-ориентированного программирования.

точка соединения-это отдельное место, где вы можете выполнить код с помощью AOP. Например, "когда метод вызывает исключение".

pointcut-это набор точек соединения. Например, "когда метод в классе Foo вызывает исключение".

Я согласен с mgroves.. Точечный разрез можно рассматривать как совокупность нескольких точек соединения. Совместная точка укажите конкретное место, где может быть реализована рекомендация, где как pointcut отражает список всех совместных точек.

JoinPoint: Joinpoint-это точки в выполнении вашей программы, где поток выполнения изменился, как перехват исключений, вызывая другой метод.

PointCut: PointCut-это в основном те точки соединения, где вы можете поместить свой совет(или вызвать аспект).

Так что в принципе PointCuts-это подмножество JoinPoints.

определения

согласно документации:

присоединиться к точке: точка во время выполнения программы, например выполнение метода или обработка исключения.

вы можете рассмотреть Совместные Точки как события при выполнении программы. Если вы используете Spring AOP, это даже ограничивается вызовом методов. AspectJ обеспечивает большую гибкость.

но вы никогда не обрабатывать все события, как вы не едите всю еду в меню, когда вы идете в ресторан (я вас не знаю, вы можете! Но, конечно же, нет). Так вы делаете выбор событий для обработки и что с ними делать. Вот идет Pointcuts. Согласно документации,

Pointcut: предикат, который соответствует join points.

тогда вы связываете, что делать с Pointcut, там идет советы. Согласно документации,

советы связан с pointcut выражение и выполняется в любой точке соединения, совпадающей с pointcut.

код

package com.amanu.example;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * @author Amanuel Nega on 10/25/16.
 */
class ExampleBussinessClass {

    public Object doYourBusiness() {
        return new Object();
    }

}

@Aspect
class SomeAspect {

    @Pointcut("execution(* com.amanu.example.ExampleBussinessClass.doYourBusiness())")
    public void somePointCut() {
    }//Empty body suffices

    @After("somePointCut()")
    public void afterSomePointCut() {
        //Do what you want to do before the joint point is executed
    }

    @Before("execution(* *(*))")
    public void beforeSomePointCut() {
        //Do what you want to do before the joint point is executed
    }

}

объяснение кода

  • ExampleBusinessClass Когда прокси-ЭД, это наша цель!
  • doYourBusiness() - это возможно совместное точка
  • SomeAspect Это наш аспект, который пересекается с несколькими проблемами такой задницы ExampleBusinessClass
  • somePointCut() это определение отрезок это соответствует нашему совместные точки
  • afterSomePointCut() это советы что будет исполнено после нашего somePointCutотрезок, что соответствует doYourBusiness()совместные точки
  • beforeSomePointCut() тоже советы что соответствует все public способ казни. В отличие от afterSomePointCut, это один использует встроенную точку вырезать объявление

вы можете посмотреть на документация если ты мне не веришь. Я надеюсь, что это поможет

pointcut определяется на реализации Аспектного класса. Точечный разрез в основном относится к выражению pointcut в Совете.

для электронной.г,

@Before("execution(* app.purchase2.service.impl.*(..))")
public void includeAddOns(RolesAllowed roles) {
..
}

вышеизложенное означает, что метод " includeAddOns "вызывается перед вызовом(из-за @Before advice) любых методов(в классах внутри пакета" app.purchase2.услуга.impl")

вся аннотация называется pointcut @Before("execution(* app.purchase2.service.impl.*(..))")

совместная точка-это фактический вызов метода, который присоединился к методу в пакете " приложение.purchase2.услуга.impl "к методу в аспектном классе" includeAddOns ()".

вы можете получить доступ к свойствам точки соединения с org.aspectj.lang.JoinPoint класса.

У AOP весной есть {советник, Совет, Pointcut, Joinpoint}

Как вы знаете, основной целью aop является отделение сквозной логики (аспекта) от кода приложения, для реализации этого весной мы используем (Совет/советник)

Pointcut используется для фильтрации, где мы хотим точно применить этот совет, например "все методы начинаются с вставки", поэтому другие методы будут исключены, поэтому у нас есть интерфейс Pointcut {ClassFilter и MethodMatcher}

таким образом, Совет-это сквозная логическая реализация, а советник-это совет плюс PointCut, если вы используете только Совет spring, он сопоставит его с советником и сделает pointcut TRUE, что означает, что ничего не блокирует. Вот почему, когда вы используете только совет, он применяется ко всем методам целевого класса, потому что вы их не фильтровали.

но Joinpoint-это место в программе, вы можете думать об этом, как отражение, когда вы получаете доступ к объекту класса, а затем вы можно получить объект метода, то вы можете вызвать любой метод в этом классе, и вот как работает компилятор, если вы думаете, как это вы можете себе представить Joinpoint.

Joinpoint может быть с полем, конструктором или методом, но весной у нас есть joinpoint только с методами, поэтому весной у нас есть (до, после, Броски, вокруг) типы Joinpoint, все они относятся к местоположениям в классе.

Как я уже упоминал, вы можете иметь совет без pointcut (без фильтра), то это будет применяется ко всем методам или у вас может быть советник, который [advice + pointcut] который будет применяться к определенным методам, но вы не можете иметь совет без joinpoint, как pointcut, вы должны указать его, и именно поэтому типы советов весной точно такие же типы, как joinpoint, поэтому при выборе совета вы неявно выбираете, какая joinpoint.

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

JoinPoint: Он указывает точку (метод) в приложении, где будет выполняться Совет.

Pointcut: это комбинация точек соединения,и она указывает, в какой точке соединения будет выполняться Совет.

точка соединения-это место, где мы фактически поставив советы

но точечный разрез-это набор точек соединения. это означает, сколько способ мы con место сквозной логики называется точка разреза