Spring AOP:JoinPoint和PointCut有什么区别?

Sau*_*til 79 aop spring aspectj spring-aop pointcut

我正在学习面向方面的编程概念和Spring AOP.我无法理解Pointcut和Joinpoint之间的区别 - 它们对我来说似乎都是一样的.Pointcut是您应用建议的地方,Joinpoint也是我们可以应用我们建议的地方.那有什么区别?

切入点的一个例子可以是:

@Pointcut("execution(* * getName()")
Run Code Online (Sandbox Code Playgroud)

什么是Joinpoint的例子?

Pre*_*raj 145

Joinpoint:连接点是应用程序的程序执行中的候选点,其中可以插入方面.这一点可以是被调用的方法,抛出的异常,甚至是被修改的字段.这些是可以将方面的代码插入到应用程序的正常流程中以添加新行为的点.

建议:这是一个对象,其中包括对系统范围的关注的API调用,这些关注表示在由点指定的连接点处执行的操作.

切入点:切入点定义了哪些连接点应该应用相关的建议.建议可以应用于AOP框架支持的任何连接点.当然,您不希望在所有可能的连接点上应用所有方面.切入点允许您指定要应用建议的位置.通常使用显式类和方法名称或通过定义匹配类和方法名称模式的正则表达式来指定这些切入点.某些AOP框架允许您创建动态切入点,以确定是否根据运行时决策应用建议,例如方法参数的值.

以下图片可以帮助您了解建议,PointCut,Joinpoints. 在此输入图像描述

资源

使用餐厅类比解释: 来自@Victor

当你去餐馆时,你会看一个菜单,看看有几个选项可供选择.您可以在菜单上订购任何一个或多个项目.但是在你真正订购它们之前,它们只是"用餐的机会".一旦你下订单,服务员把它带到你的餐桌,这是一顿饭.

Joinpoints是菜单上的选项,Pointcuts是您选择的项目.

Joinpoint是代码中的一个机会,您可以应用一个方面......只是一个机会.一旦你抓住这个机会并选择一个或多个Joinpoints并对它们应用一个方面,你就有了一个Pointcut.

  • 这应该标记为正确答案.只是添加更多信息,请查看Cragi Walls的答案...... http://www.coderanch.com/t/485525/Spring/Difference-Joint-Point-Point-Cut. (3认同)
  • 要点:切入点定义应该应用什么连接点建议+1 (2认同)

Suj*_*ddi 28

要了解连接点和切入点之间的区别,请将切入点视为指定编织规则并将连接点作为满足这些规则的情况.

在下面的例子中,

  @Pointcut("execution(* * getName()")  
Run Code Online (Sandbox Code Playgroud)

Pointcut定义规则说,建议应该应用于任何包中任何类中的getName()方法,joinpoints将是类中存在的所有getName()方法的列表,以便可以对这些方法应用建议.

(对于Spring,Rule仅适用于托管bean,建议只能应用于公共方法).


Kri*_*hna 27

JoinPoints:这些基本上位于实际业务逻辑中,您希望插入一些必要但又不属于实际业务逻辑的其他功能.JoinPints的一些示例是:方法调用,正常返回方法,抛出异常的方法,实例化对象,引用对象等等......

切入点:切入点类似于正则表达式,用于标识连接点.Pontcuts使用"切入点表达式语言"表示.切入点是需要应用跨领域关注点的执行流程点.Joinpoint和Pointcut之间存在差异; 连接点更通用,代表任何控制流程,我们可以选择"引入跨领域的关注点,而切入点识别这样的连接点,其中'我们想要'引入跨领域的关注点.

  • 连接点 - 应用/运行建议代码的潜在位置。切入点 - 实际选择的用于执行建议的连接点。 (2认同)

Dev*_*v S 20

对于AOP概念不熟悉的人的Layman解释.这不是详尽无遗的,但应该有助于理解这些概念.如果您已熟悉基本术语,则可以立即停止阅读.

假设您有一个普通的Employee类,并且每次调用这些方法时都希望执行某些操作.

class Employee{
    public String getName(int id){....}
    private int getID(String name){...}
}
Run Code Online (Sandbox Code Playgroud)

这些方法称为JoinPoints.我们需要一种方法来识别这些方法,以便框架可以在所有类中找到方法.它已经加载了方法.因此,我们将编写一个正则表达式来匹配这些方法的签名.虽然下面会有更多内容,但松散地说这个正则表达式定义了Pointcut.例如

* * mypackage.Employee.get*(*)
Run Code Online (Sandbox Code Playgroud)

First*用于修饰符public/private/protected/default.第二个*用于该方法的返回类型.

但是你还需要告诉另外两件事:

  1. 应该何时采取行动 - 例如方法执行之前/之后或异常
  2. 什么它匹配时,应该把它做(也许只是打印一条消息)

这两者的组合称为建议.

你可以想象,你必须编写一个能够做#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
Run Code Online (Sandbox Code Playgroud)

一旦你开始使用这些,你最终可能会指定许多@ 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() {....}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,你也想把这个整个逻辑包装在一个叫做Aspect的类中,你会编写一个类:

@Aspect
public class MyAwesomeAspect{....}
Run Code Online (Sandbox Code Playgroud)

要使所有这些工作正常工作,您必须告诉Spring解析类以阅读,理解并对@ AOP关键字采取措施.一种方法是在spring config xml文件中指定以下内容:

<aop:aspectj-autoproxy>


kri*_*aex 10

将AspectJ之类的AOP语言与SQL之类的数据查询语言进行比较,您可以将连接点(即代码中可编织方面代码的所有位置)视为具有多行的数据库表.切入点就像一个SELECT stamement,可以选择用户定义的行/连接点子集.编织到选定位置的实际代码称为建议.


Mat*_*ves 6

两者都属于面向方面编程的"位置".

连接点是您可以使用AOP执行代码的单独位置.例如"当方法抛出异常时".

切入点是连接点的集合.例如"当Foo类中的方法抛出异常时".


Ama*_*ega 6

定义

根据文件:

连接点:程序执行期间的一个点,例如方法的执行或异常的处理.

您可以将联合点视为执行程序的事件.如果您使用的是Spring AOP,这甚至仅限于调用方法.AspectJ提供了更大的灵活性.

但是你从来没有处理过所有的事件,因为当你去餐馆时你不吃菜单里的所有食物(我不认识你,你可能!但是,我当然不会).因此,您可以选择要处理的事件以及如何处理它们.这里是切入点.根据文档,

切入点:匹配连接点的谓词.

然后你关联如何处理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
    }

}
Run Code Online (Sandbox Code Playgroud)

代码说明

  • ExampleBusinessClass 代理时,是我们的目标!
  • doYourBusiness()是一个可能的联合点
  • SomeAspect 是我们的方面,跨越多个问题,如屁股 ExampleBusinessClass
  • somePointCut()是与我们的关节点匹配的切点的定义
  • afterSomePointCut()是一个建议,将在我们的somePointCut 点切割匹配关节点后执行doYourBusiness()
  • beforeSomePointCut()也是一个匹配所有方法执行的建议public.与afterSomePointCut此不同,这个使用内联点切割声明

如果你不相信我,你可以查看文档.我希望这有帮助

  • 简单的解释。只需引用三段文字就足以理解。谢谢。 (2认同)

小智 5

JoinPoint:Joinpoint 是程序执行中的点,其中执行流程发生了变化,例如异常捕获、调用其他方法。

PointCut:PointCut 基本上是那些可以放置建议(或调用方面)的连接点。

所以基本上PointCuts 是 JoinPoints 的子集