Spring AOP: JoinPoint ve PointCut arasındaki fark nedir?


88

Görünüşe Dayalı Programlama kavramlarını ve Spring AOP'u öğreniyorum. Pointcut ve Joinpoint arasındaki farkı anlayamıyorum - ikisi de benim için aynı görünüyor. Pointcut, tavsiyenizi uyguladığınız yerdir ve bir Joinpoint de tavsiyemizi uygulayabileceğimiz bir yerdir. O zaman fark nedir?

Nokta kesimine bir örnek şunlar olabilir:

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

Bir Joinpoint örneği ne olabilir?

Yanıtlar:


162

Birleştirme noktası: Birleştirme noktası , uygulamanın Program Yürütülmesindeki aday noktadır . Bu nokta, çağrılan bir yöntem, atılan bir istisna ve hatta değiştirilen bir alan olabilir. Bunlar, görünüm kodunuzun yeni davranış eklemek için uygulamanızın normal akışına eklenebileceği noktalardır.

Tavsiye: Bu, bir nokta ile belirtilen bir birleşme noktasında gerçekleştirilecek eylemi temsil eden sistem genelindeki endişelere API çağrılarını içeren bir nesnedir.

Pointcut: Pointcut, hangi birleşim noktalarında, ilgili Tavsiyenin uygulanması gerektiğini tanımlar. Tavsiye, AOP çerçevesi tarafından desteklenen herhangi bir birleşme noktasında uygulanabilir. Elbette, tüm yönlerinizi olası tüm birleşim noktalarına uygulamak istemezsiniz. Nokta kesimleri, tavsiyenizin uygulanmasını istediğiniz yeri belirlemenize olanak tanır. Genellikle bu nokta kesimlerini açık sınıf ve yöntem adlarını kullanarak veya eşleşen sınıf ve yöntem adı modellerini tanımlayan normal ifadeler aracılığıyla belirtirsiniz. Bazı AOP çerçeveleri, yöntem parametrelerinin değeri gibi çalışma zamanı kararlarına dayalı tavsiyelerin uygulanıp uygulanmayacağını belirleyen dinamik nokta kesimleri oluşturmanıza olanak tanır.

Aşağıdaki görüntü, Tavsiye, PointCut, Birleşme Noktalarını anlamanıza yardımcı olabilir. görüntü açıklamasını buraya girin

Kaynak

Restoran Analojisini Kullanarak Açıklama: Kaynak @Victor

Bir restorana gittiğinizde, bir menüye bakarsınız ve aralarından seçim yapabileceğiniz birkaç seçenek görürsünüz. Menüdeki öğelerden birini veya birkaçını sipariş edebilirsiniz. Ama onları gerçekten sipariş edene kadar, bunlar sadece "yemek yeme fırsatıdır". Siparişi verdikten ve garson onu masanıza getirdiğinde, bir yemektir.

Birleşme noktaları menüdeki seçeneklerdir ve Pointcuts seçtiğiniz öğelerdir.

Joinpoint, kod içinde sizin için bir özelliği uygulamanız için bir fırsattır ... sadece bir fırsat. Bu fırsatı değerlendirip bir veya daha fazla Birleşme Noktası seçip bunlara bir özellik uyguladığınızda, bir Noktasal Kesiminiz olur.

Kaynak Wiki :

Bir Birleşme Noktası, bir programın kontrol akışında, kontrol akışının iki farklı yoldan ulaşabildiği bir noktadır (IMO: bu nedenle eklem çağrısı).

Tavsiye , diğer işlevleri değiştiren bir işlev sınıfını tanımlar

Bir Pointcut eşleşen bir p noktaları birleştirme Joinpoint yani dizi attern.


3
Bu doğru cevap olarak işaretlenmelidir. Daha fazla bilgi eklemek için Cragi Walls cevabına bakın ... coderanch.com/t/485525/Spring/Difference-Joint-Point-Point-Cut .
Victor

2
Konuya göre: Nokta kesiti, hangi bağlantı noktalarında tavsiyenin uygulanması gerektiğini tanımlar +1
Naman Gala

Sadece onay, more Joinpoints and apply an aspect to them, you've got a Pointcut. görünüş veya onlara tavsiye için mi?
Asif Mushtaq

@Premraj Yani, analojinize göre öğün siparişi vereceksiniz. Haklı mıyım
Vishwas Atrey

Restoran benzetmesi JoinPoints ve nokta kesimleri arasındaki karışıklığı gidermeye yardımcı oldu, Teşekkürler!
SM

31

Bir birleştirme noktası ile nokta kesimi arasındaki farkı anlamak için nokta kesimlerini dokuma kurallarını belirleme olarak ve birleştirme noktalarını bu kuralları karşılayan durumlar olarak düşünün.

Aşağıdaki örnekte,

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

Pointcut, herhangi bir paketteki herhangi bir sınıfta bulunan getName () yöntemine tavsiye uygulanması gerektiğini söyleyen kuralları tanımlar ve birleştirme noktaları, sınıflarda bulunan tüm getName () yöntemlerinin bir listesi olur, böylece bu yöntemlere tavsiye uygulanabilir.

(İlkbahar durumunda, Kural yalnızca yönetilen çekirdeklere uygulanacaktır ve tavsiye yalnızca genel yöntemlere uygulanabilir).


1
"Pointcut, herhangi bir paketteki herhangi bir sınıfta bulunan getName () yöntemine tavsiye uygulanması gerektiğini söyleyen kuralları tanımlar ve birleştirme noktaları, sınıflarda bulunan tüm getName () yöntemlerinin bir listesi olur, böylece bu yöntemlere tavsiye uygulanabilir." Üzgünüm ama bu daha da kafa karıştırıcı hale geliyor. Bana gerçek dünya günlük yaşam senaryosunda bir benzetme verebilir misiniz?
Saurabh Patil

28

JoinPoints: Bunlar, temel olarak, gerekli olan ancak gerçek iş mantığının bir parçası olmayan bazı çeşitli işlevleri eklemek istediğiniz gerçek iş mantığındaki yerlerdir. JoinPints'in bazı örnekleri şunlardır: yöntem çağrısı, normal olarak geri dönen yöntem, bir istisna atan yöntem, bir nesneyi örneklemek, bir nesneye başvurmak, vb.

Pointcuts: Pointcuts, birleşme noktalarını tanımlamak için kullanılan normal ifadeler gibi bir şeydir. Pontcut'lar "noktasal ifade dili" kullanılarak ifade edilir. Noktasal kesimler, kesişen konunun uygulanması gereken uygulama akış noktalarıdır. Joinpoint ve Pointcut arasında bir fark vardır; Birleşme noktaları daha geneldir ve kesişen bir endişeyi 'ortaya koymayı' seçebileceğimiz 'herhangi bir kontrol akışını temsil ederken, nokta kesimleri,' kesişen bir endişeyi 'ortaya koymak' istediğimiz 'bu tür birleşme noktalarını tanımlar.


1
Joinpoint - Tavsiye kodunu uygulamak / çalıştırmak için potansiyel yerler. Pointcut - tavsiyenin yürütülmesi için seçilen gerçek birleşme noktaları.
user104309

26

AOP kavramlarında yeni olan biri için meslekten olmayan açıklama. Bu ayrıntılı değildir, ancak kavramların anlaşılmasına yardımcı olacaktır. Temel jargona zaten aşina iseniz, şimdi okumayı bırakabilirsiniz.

Normal bir Sınıf Çalışanınız olduğunu ve bu yöntemler her çağrıldığında bir şeyler yapmak istediğinizi varsayalım.

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

bu yöntemlere JoinPoints adı verilir . Bu yöntemleri tanımlamanın bir yoluna ihtiyacımız var, böylece çerçeve, yüklediği tüm sınıflar arasında yöntemleri bulabilir. Bu nedenle, bu yöntemlerin imzasıyla eşleşecek bir düzenli ifade yazacağız. Aşağıda göreceğiniz gibi daha fazlası olsa da, genel olarak bu normal ifade Pointcut'ı tanımlayan şeydir . Örneğin

* * mypackage.Employee.get*(*)

İlk *, genel / özel / korumalı / varsayılan değiştirici içindir. İkinci *, yöntemin dönüş türü içindir.

Ama sonra iki şeyi daha söylemelisin:

  1. Ne zaman bir eylem gerçekleştirilmelidir - örneğin, yöntemin yürütülmesinden önce / sonra VEYA istisna durumunda
  2. Eşleştiğinde ne yapmalı (belki sadece bir mesaj yazdırın)

Bu ikisinin birleşimine Tavsiye denir .

Tahmin edebileceğiniz gibi, # 2'yi yapabilmek için bir fonksiyon yazmanız gerekir. Yani temeller böyle görünebilir.

Not: Açık bir ifadeyle, kelime kullanarak regex yerine * * mypackage.Employee.get*(*). Gerçekte tam ifade, tanımın içine girer.

@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

Bunları biraz kullanmaya başladığınızda, birçok @ After / @ Before / @ Around tavsiyesi belirlemeye başlayabilirsiniz. Tekrarlanan düzenli ifadeler sonunda şeyler kafa karıştırıcı ve bakımı zorlaştırır sona erecek. Yani yaptığımız şey, ifadeye sadece bir isim veriyoruz ve onu Aspect sınıfında başka her yerde kullanıyoruz.

@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() {....}

BTW, tüm bu mantığı Aspect denen bir sınıfa sarmak istersiniz ve bir sınıf yazarsınız:

@Aspect
public class MyAwesomeAspect{....}

Tüm bunların işe yaraması için Spring'e sınıfları ayrıştırmasını, @ AOP anahtar kelimelerini okumasını, anlamasını ve bunlarla ilgili işlem yapmasını söylemeniz gerekir. Bunu yapmanın bir yolu, bahar yapılandırma xml dosyasında aşağıdakileri belirtmektir:

<aop:aspectj-autoproxy>


1
AOP'de yeniyim ve bu açıklama, Tavsiye / Nokta Kesintileri / Birleştirme Noktaları arasındaki ilişkiyi oldukça net bir şekilde anlamama yardımcı oldu.
Jatin Shashoo

Bu, efendim, yeni başlayanlar için çok daha iyi bir açıklama. Teşekkürler
Aakash

11

AspectJ gibi bir AOP dilini SQL gibi bir veri sorgulama diliyle karşılaştırdığınızda, birleşim noktalarını (yani kodunuzda en boy kodunu örebileceğiniz tüm yerler) birçok satır içeren bir veritabanı tablosu olarak düşünebilirsiniz. Nokta kesimi, kullanıcı tanımlı bir satır / birleşme noktası alt kümesini seçebilen bir SELECT stamement gibidir. Bu seçilmiş yerlere ördüğünüz gerçek koda tavsiye denir.


9

Tanımlar

Belgelere göre:

Birleşme noktası: bir yöntemin yürütülmesi veya bir istisnanın işlenmesi gibi bir programın yürütülmesi sırasında bir noktadır.

Ortak Noktaları bir programın yürütülmesindeki olaylar olarak düşünebilirsiniz . Spring AOP kullanıyorsanız, bu yöntemlerin başlatılmasıyla sınırlıdır. AspectJ daha fazla esneklik sağlar.

Ancak bir restorana gittiğinizde menüdeki tüm yiyecekleri yemediğiniz için tüm olaylarla asla ilgilenmezsiniz (Seni tanımıyorum, yapabilirsin! Ama kesinlikle yapmıyorum). Böylece, ele alınacak olayları ve bunlarla ne yapacağınızı seçersiniz. İşte Pointcuts . Belgelere göre,

Pointcut : birleşme noktalarıyla eşleşen bir yüklem .

Sonra Pointcut ile ne yapılacağını ilişkilendirirsin , Tavsiye gelir . Belgelere göre,

Tavsiye bir nokta kesim ifadesiyle ilişkilendirilir ve nokta kesimi ile eşleşen herhangi bir birleşme noktasında çalışır.

Kod

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
    }

}

Kod Açıklaması

  • ExampleBusinessClass vekaletname verildiğinde, hedefimiz!
  • doYourBusiness()olası bir ortak nokta
  • SomeAspect birden fazla endişeyle kesişen yönümüzdür. ExampleBusinessClass
  • somePointCut()ortak noktamızla eşleşen bir nokta kesiminin tanımıdır
  • afterSomePointCut()ortak nokta ile eşleşen nokta kesimimizden sonra uygulanacak bir tavsiyedirsomePointCut doYourBusiness()
  • beforeSomePointCut()ayrıca tüm yöntem uygulamalarına uyan bir tavsiyedirpublic . Bunun aksine afterSomePointCut, bu bir satır içi nokta kesme bildirimi kullanıyor

Bana inanmıyorsanız belgelere bakabilirsiniz . Umarım bu yardımcı olur


1
Basit açıklama. Anlamak için sadece üç alıntı metni yeterlidir. Teşekkürler.
TRiNE

6

Her ikisi de görünüm odaklı programlamanın "nerede" ile ilgilidir.

Birleştirme noktası, AOP ile kod çalıştırabileceğiniz ayrı bir yerdir. Örneğin, "bir yöntem bir istisna attığında".

Nokta kesimi, birleştirme noktaları koleksiyonudur. Örneğin, "Foo sınıfındaki bir yöntem bir istisna attığında".


5

JoinPoint : Joinpoint, program yürütmenizdeki yürütme akışının İstisna yakalama, Diğer yöntemi çağırma gibi değiştiği noktalardır.

PointCut : PointCut, temelde tavsiyenizi koyabileceğiniz (veya yönünüzü arayabileceğiniz) birleşme noktalarıdır.

Yani temelde PointCuts, JoinPoints'in alt kümesidir .


3

İlkbaharda AOP'de {Advisor, Advice, Pointcut, Joinpoint} vardır

Bildiğiniz gibi aop'un temel amacı, kesişen endişe mantığını (Aspect) uygulama kodundan ayırmaktır, bunu İlkbaharda uygulamak için kullanıyoruz (Tavsiye / Danışman)

Pointcut, bu tavsiyeyi tam olarak uygulamak istediğimiz yeri filtrelemek için kullanılır, "tüm yöntemler insert ile başlar" gibi, böylece diğer yöntemler hariç tutulacaktır, bu yüzden Pointcut arayüzünde {ClassFilter ve MethodMatcher} var

Öyleyse Tavsiye, çapraz kesen mantık uygulamasıdır ve Danışman, tavsiye artı PointCut'dur, eğer sadece tavsiye kullanırsanız, yay onu danışmana eşler ve nokta kesimini DOĞRU yapar, yani hiçbir şeyi engellemeyin. Bu nedenle, sadece tavsiye kullandığınızda, onları filtrelemediğiniz için hedef sınıfın tüm yöntemlerine uygulanır.

Ancak Joinpoint, programdaki bir konumdur, Class nesnesine eriştiğinizde yansıma gibi düşünebilirsiniz ve ardından Method nesnesini elde edebilirsiniz, sonra bu sınıftaki herhangi bir yöntemi çağırabilirsiniz ve eğer isterseniz derleyici böyle çalışır. bu Joinpoint'i hayal edebilirsiniz.

Joinpoint, alan, kurucu veya yöntemle olabilir, ancak İlkbaharda yalnızca yöntemlerle birleştirme noktasına sahibiz, bu nedenle İlkbaharda (Before, After, Throws, Around) Joinpoint türlerine sahibiz, hepsi sınıftaki konumları ifade eder.

Bahsettiğim gibi, nokta kesmeden (filtresiz) tavsiye alabilirsiniz, o zaman tüm yöntemlere uygulanacaktır veya belirli yöntemlere uygulanacak olan [öneri + nokta] olan bir danışmanınız olabilir ancak olmadan tavsiye alamazsınız. birleştirme noktası gibi nokta kesimi gibi, onu belirtmeniz gerekir ve bu nedenle bahardaki tavsiye türleri birleştirme noktası ile tamamen aynıdır, bu nedenle bir tavsiye seçtiğinizde, hangi birleşme noktasını örtük olarak seçersiniz.

Özetlemek gerekirse, tavsiye, hedef sınıfa bakış açınız için uygulama mantığıdır, bu tavsiyede çağırmadan önce, çağırmadan sonra, fırlatmadan sonra veya çağırmadan sonra olduğu gibi bir birleşme noktası olmalıdır, ardından nokta kesimini kullanarak tam olarak uygulamak istediğiniz yere filtre uygulayabilirsiniz. yöntemleri filtreleyin veya nokta kesmesiz (filtre yok), böylece sınıfın tüm yöntemlerine uygulanacaktır.


3

Aspect - sınıfı uygulamasında bir nokta kesimi tanımlanır. Nokta kesimi temel olarak tavsiye içerisindeki nokta kesim ifadesine atıfta bulunur.

Örneğin,

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

Yukarıdaki, "includeAddOns" yönteminin herhangi bir yöntemi ("app.purchase2.service.impl" paketindeki sınıflarda) çağırmadan önce çağrıldığı anlamına gelir (@Before tavsiyesi nedeniyle)

Tüm ek açıklamaya nokta kesimi denir @Before("execution(* app.purchase2.service.impl.*(..))")

Ortak nokta, "app.purchase2.service.impl" paketindeki yöntemi "includeAddOns ()" yön sınıfındaki yönteme birleştiren gerçek yöntem çağrısıdır.

org.aspectj.lang.JoinPointSınıf ile birleşme noktasının özelliklerine erişebilirsiniz .


İyi cevap! Sonunda farkı anladım!
Dante

2

Mgroves ile aynı fikirdeyim .. Bir nokta kesimi, birden fazla eklem noktasının bir toplamı olarak düşünülebilir. Ortak nokta, tavsiyenin uygulanabileceği belirli konumu belirtir; burada nokta kesimi tüm ortak noktaların listesini yansıtır.


0

JoinPoint: Tavsiyenin yürütüleceği uygulamada bir nokta (yöntem) belirtir.

Pointcut: JoinPoint'lerin birleşimidir ve hangi JoinPoint Advice'ının yürütüleceğini belirtir.


-5

birleşme noktası, tavsiyeleri yerleştirdiğimiz bir yerdir

ancak nokta kesimi, birleşme noktalarının toplamıdır. Bu, çapraz kesme mantığını kaç yöne yerleştirdiğimizin nokta kesme olarak adlandırıldığı anlamına gelir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.