Spring AOP: Какая разница между JoinPoint и PointCut?

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

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

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

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

Ответ 1

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

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

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

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

Источник

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

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

Точки соединения - это опции в меню, а Точки - это элементы, которые вы выбираете.

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

Источник Wiki:

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

Совет описывает класс функций, которые модифицируют другие функции

pointcut - это набор точек соединения.

Ответ 2

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

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

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

* * mypackage.Employee.get*(*)

First * для модификатора public/private/protected/default. Second * - для типа возвращаемого метода.

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

  • Когда должно быть предпринято действие - например, до/после выполнения метода ИЛИ в случае исключения
  • Что следует делать, когда оно соответствует (возможно, просто распечатать сообщение)

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

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

Примечание. Для ясности используйте слово REGEX вместо * * 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

Как только вы начнете использовать их совсем немного, вы можете указать много @После/@Перед/@Вокруг советов. Повторные регулярные выражения, в конечном счете, в конечном итоге делают вещи запутанными и трудными для поддержания. Итак, что мы делаем, мы просто даем имя этому выражению и используем его везде в классе Aspect.

@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, и вы должны написать класс:

@Aspect
public class MyAwesomeAspect{....}

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

<aop:aspectj-autoproxy>

Ответ 5

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

Ответ 6

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

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

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

Ответ 7

Определения

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

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

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

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

Pointcut: a predicate that matches 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 after 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, в этом используется встроенная декларация обрезки точек

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

Ответ 8

JoinPoint. Точка соединения - это точки в выполнении вашей программы, когда поток выполнения был изменен, как "Исправление исключений", "Вызов другого метода".

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

Итак, в основном PointCuts - это подмножество JoinPoints.

Ответ 9

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

Ответ 10

В реализации Aspect-класса определяется pointcut. Вырезание точки в основном относится к выражению pointcut в совете.

Например,

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

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

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

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

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

Ответ 11

AOP в spring имеет {Advisor, Advice, Pointcut, Joinpoint}

Как вы знаете, основная цель aop - развязать межсекторальную логику (Aspect) от кода приложения, чтобы реализовать это в spring, мы используем (Advice/Advisor)

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

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

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

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

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

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

Ответ 12

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

Pointcut:. Это комбинация JoinPoints, и она указывает, с какими будет выполняться совет JoinPoint.

Ответ 13

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

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