Весняний AOP: Яка різниця між JoinPoint та PointCut?


88

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

Прикладом вирізання точки може бути:

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

Що може бути прикладом Joinpoint?

Відповіді:


161

Точка об’єднання: Точка об’єднання - це точка- кандидат у виконанні програми, до якої може бути підключений аспект. Ця точка може бути викликаним методом, викидом або навіть полем, яке модифікується. Це точки, де код вашого аспекту можна вставити в звичайний потік вашої програми, щоб додати нову поведінку.

Порада: Це об’єкт, який включає виклики API до загальносистемних проблем, що представляють дію, яку потрібно виконати в точці з’єднання, вказаній точкою.

Точковий наріз: точковий наріз визначає, до яких точок об’єднання слід застосовувати пов’язані поради. Поради можна застосовувати в будь-якій точці з'єднання, що підтримується структурою AOP. Звичайно, ви не хочете застосовувати всі свої аспекти на всіх можливих точках об’єднання. Pointcuts дозволяють вказати, де ви хочете застосовувати свою пораду. Часто ви вказуєте ці пункти, використовуючи явні імена класів та методів або за допомогою регулярних виразів, що визначають відповідні шаблони імен класів та методів. Деякі фреймворки AOP дозволяють створювати динамічні точкові скорочення, які визначають, чи застосовувати поради на основі рішень під час виконання, таких як значення параметрів методу.

Наступне зображення може допомогти вам зрозуміти Advice, PointCut, Joinpoints. введіть тут опис зображення

Джерело

Пояснення за допомогою ресторанної аналогії: Джерело @Victor

Коли ви виходите в ресторан, ви дивитесь на меню і бачите кілька варіантів на вибір. Ви можете замовити один або декілька пунктів меню. Але поки ви насправді не замовите їх, вони є лише «можливостями повечеряти». Як тільки ви зробите замовлення, і офіціант принесе його до вашого столу, це вечеря.

Точки об’єднання - це опції в меню, а Точки - це вибрані вами елементи.

Joinpoint - це можливість у коді застосувати аспект ... просто можливість. Після того, як ви скористаєтеся цією можливістю та виберіть одну або кілька точок об’єднання та застосуєте до них аспект, ви отримаєте Pointcut.

Джерело Wiki :

Приєднатися точка є точкою в потоці управління програми , де керуючий потік може прибути через два різних шляхи (IMO: ось чому виклик суглоба).

Порада описує клас функцій, які змінюють інші функції

Зріз точки являє собою набір точок з'єднання.


3
Це слід позначити як правильну відповідь. Щоб додати трохи більше інформації, подивіться на відповідь на стіни Крегі ... coderanch.com/t/485525/Spring/Difference-Joint-Point-Point-Cut .
Віктор

2
До суті: точковий виріз визначає, в яких точках об’єднання слід застосовувати поради +1
Naman Gala

Тільки для підтвердження, more Joinpoints and apply an aspect to them, you've got a Pointcut. аспекту для них чи поради для них?
Асіф Муштак

@Premraj Отже, згідно з вашими аналогічними порадами, ви будете замовляти їжу. Чи правий я?
Vishwas Atrey

Аналогія ресторану допомогла усунути плутанину між точками об’єднання та точками, спасибі!
SM

30

Щоб зрозуміти різницю між точкою з’єднання та точковою вирізкою, подумай про точкових вирізах як про вказівку правил плетіння, а про точки об’єднання - як ситуації, що задовольняють ці правила.

У наведеному нижче прикладі

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

Pointcut визначає правила, говорячи, що пораду слід застосовувати щодо методу getName (), який присутній у будь-якому класі будь-якого пакету, а точки об’єднання будуть списком усіх методів getName (), що є у класах, щоб можна було застосовувати поради щодо цих методів.

(У випадку весни правило застосовуватиметься лише до керованих зерен, а поради можна застосовувати лише до загальнодоступних методів).


1
"Pointcut визначає правила, в яких говориться, що пораду слід застосовувати щодо методу getName (), який присутній у будь-якому класі будь-якого пакета, а точки об’єднання будуть списком усіх методів getName (), що є у класах, щоб можна було застосовувати поради щодо цих методів." Вибачте, але це стає все більш заплутаним. Чи можете ви дати мені аналогію у реальному повсякденному життєвому сценарії?
Saurabh Patil

28

Точки об’єднання: Це в основному місця у фактичній бізнес-логіці, де ви хочете вставити різні функції, які є необхідними, але не є частиною фактичної бізнес-логіки. Деякі приклади JoinPints: виклик методу, нормальний повернення методу, метод, що створює виняток, створення екземпляра об’єкта, посилання на об’єкт тощо ...

Pointcuts: Pointcuts - це щось на зразок регулярних виразів, які використовуються для ідентифікації точок об’єднання. Понткути виражаються за допомогою "мови виразів точки". Точкові скорочення - це точки потоку виконання, де потрібно застосувати наскрізну проблему. Існує різниця між Joinpoint та Pointcut; Точки з'єднання є більш загальними і представляють будь-який потік управління, коли ми "можемо вирішити" внести наскрізну проблему, тоді як pointcuts ідентифікує такі точки з'єднання, де "ми хочемо" ввести наскрізну проблему.


1
Точка об’єднання - Потенційні місця для застосування / запуску коду поради. Pointcut - фактично вибрані точки об’єднання для виконання порад.
user104309

25

Пояснення для непрофесіоналів для тих, хто новачок у концепціях AOP. Це не є вичерпним, але має допомогти зрозуміти поняття. Якщо ви вже знайомі з основним жаргоном, можете перестати читати зараз.

Припустимо, у вас нормальний працівник класу, і ви хочете щось робити щоразу, коли викликаються ці методи.

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

ці методи називаються JoinPoints . Нам потрібен спосіб ідентифікувати ці методи, щоб фреймворк міг знайти методи серед усіх класів. Методів, які він завантажив. Тож ми напишемо регулярний вираз, щоб відповідати підпису цих методів. Хоча це ще щось, як ви побачите нижче, але вільно цей регулярний вираз визначає Pointcut . напр

* * mypackage.Employee.get*(*)

Перший * призначений для модифікатора public / private / protected / default. Другий * - для типу повернення методу.

Але тоді вам потрібно сказати ще дві речі:

  1. Коли слід вживати дії - наприклад, до / після виконання методу АБО на виняток
  2. Що робити, коли воно збігається (можливо, просто надрукувати повідомлення)

Поєднання цих двох називається порадою .

Як ви можете собі уявити, вам доведеться написати функцію, щоб мати змогу виконати No2. Ось так це могло б виглядати для основ.

Примітка: Для наочності використовуйте слово 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

Як тільки ви почнете користуватися цими трохи, ви можете в кінцевому підсумку вказати багато порад @ After / @ Before / @ Around. Ці повторні регулярні вирази будуть в кінцевому підсумку робить речі заплутаною і складною в обслуговуванні. Отже, що ми робимо, ми просто даємо назву виразу і використовуємо його скрізь в іншому класі класу 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. Один із способів це зробити - вказати наступне у весняному конфігураційному xml-файлі:

<aop:aspectj-autoproxy>


1
Я новачок в AOP, і це пояснення допомогло мені зрозуміти взаємозв'язок між Advice / Pointcuts / JoinPoints.
Jatin Shashoo

Це, сер, набагато краще пояснення для новачка. Дякую
Aakash

11

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


9

Визначення

Відповідно до документації:

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

Ви можете розглянути спільні бали як події у виконанні програми. Якщо ви використовуєте Spring AOP, це навіть обмежується викликом методів. AspectJ забезпечує більшу гнучкість.

Але ви ніколи не обробляєте всі події, оскільки не їсте всю їжу в меню, коли ходите до ресторану (я вас не знаю, можливо! Але, звичайно, ні). Тож ви робите вибір подій, які потрібно обробити, і що з ними робити. Тут іде Pointcuts . Відповідно до документації,

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цього, тут використовується вбудована декларація вирізання точок

Ви можете подивитися документацію, якщо не вірите мені. Сподіваюся, це допоможе


1
Просте пояснення. Для розуміння достатньо лише трьох наведених текстів. Дякую.
TRiNE

6

І те, і інше стосується "де" аспектно-орієнтованого програмування.

Точка приєднання - це окреме місце, де ви можете виконувати код за допомогою AOP. Наприклад, "коли метод видає виняток".

Точковий набір - це сукупність точок об’єднання. Наприклад, "коли метод у класі Foo видає виняток".


4

JoinPoint : Joinpoint - це точки у виконанні вашої програми, де потік виконання змінився, як виняток вилучення, виклик іншого методу.

PointCut : PointCut - це в основному ті об’єднані точки, де ви можете подати свою пораду (або аспект дзвінка).

Отже, в основному PointCuts - це підмножина JoinPoints .


3

AOP навесні має {Advisor, Advice, Pointcut, Joinpoint}

Як ви знаєте, основною метою aop є відокремлення наскрізної логіки (Aspect) від коду програми, для реалізації цього навесні ми використовуємо (Advice / Advisor)

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

Отже, «Порада» - це наскрізна реалізація логіки, а «Радник» - це порада плюс PointCut, якщо ви користуєтесь лише порадою, весна зв’яже її з радником і зробить точку ІСТИНОЮ, що означає нічого не блокувати. Ось чому, коли ви використовуєте лише поради, це застосовується до всіх методів цільового класу, оскільки ви їх не фільтрували.

Але Joinpoint - це місце в програмі, ви можете думати про це як про відображення при доступі до об'єкта Class, а потім ви можете отримати об'єкт Method, тоді ви можете викликати будь-який метод у цьому класі, і ось як працює компілятор, якщо ви думаєте, що це ви можете собі уявити Joinpoint.

Точка об'єднання може бути з полем, конструктором або методом, але навесні ми маємо точку об'єднання лише з методами, тому навесні ми маємо типи Joinpoint (до, після, кидки, навколо), всі вони посилаються на місця в класі.

Як я вже згадував, ви можете отримати пораду без pointcut (без фільтра), тоді вона буде застосована до всіх методів, або ви можете мати консультанта, який є [консультація + pointcut], який застосовуватиметься до конкретних методів, але ви не можете отримати поради без joinpoint, як pointcut, ви повинні вказати його, і тому типи рекомендацій навесні - це точно ті самі типи, що і joinpoint, тому, вибираючи пораду, ви неявно вибираєте, яку точку з'єднання.

Підсумовуючи, порада - це логіка реалізації вашого аспекту для цільового класу; ця порада повинна мати точку об’єднання, як до виклику, після виклику, після викидання або навколо виклику, тоді ви можете відфільтрувати, де саме ви хочете застосувати це, використовуючи pointcut для відфільтруйте методи або не використовуйте pointcut (без фільтра), щоб він застосовувався до всіх методів класу.


3

Точковий виріз визначається в реалізації класу Aspect. Вирізання точок в основному відноситься до вираження точки в рамках поради.

Наприклад,

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

Вищезазначене означає, що метод "includeAddOns" викликається перед викликом (завдяки пораді @Before) будь-яких методів (у класах в пакеті "app.purchase2.service.impl")

Вся анотація називається точковим @Before("execution(* app.purchase2.service.impl.*(..))")

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

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


Гарна відповідь! Нарешті я зрозумів різницю!
Данте,

2

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


0

JoinPoint: Він визначає точку (метод) у програмі, де буде виконуватися Порада.

Pointcut: Це комбінація JoinPoints, і вона визначає те, за яким буде виконуватися порада JoinPoint.


-5

точка приєднання - це місце, де ми фактично розміщуємо поради

але вирізання точок - це набір точок об’єднання. це означає, скільки способів, за якими ми розміщуємо наскрізну логіку, називається точковим вирізанням

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.