Spring AOP:JoinPoint 和 PointCut 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15447397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring AOP: What's the difference between JoinPoint and PointCut?
提问by Saurabh Patil
I'm learning Aspect Oriented Programming concepts and Spring AOP. I'm failing to understand the difference between a Pointcut and a Joinpoint - both of them seem to be the same for me. A Pointcut is where you apply your advice and a Joinpoint is also a place where we can apply our advice. Then what's the difference?
我正在学习面向方面的编程概念和 Spring AOP。我无法理解切入点和连接点之间的区别 - 它们对我来说似乎是一样的。切入点是您应用建议的地方,连接点也是我们应用建议的地方。那有什么区别呢?
An example of a pointcut can be:
一个切入点的例子可以是:
@Pointcut("execution(* * getName()")
What can be an example of a Joinpoint?
什么是 Joinpoint 的示例?
回答by Premraj
Joinpoint:A joinpoint is a candidatepoint in the Program Executionof the application where an aspect can be plugged in. This point could be a method being called, an exception being thrown, or even a field being modified. These are the points where your aspect's code can be inserted into the normal flow of your application to add new behavior.
连接点:连接点是应用程序程序执行中可以插入方面的候选点。这个点可以是一个方法被调用,一个异常被抛出,甚至是一个被修改的字段。这些是可以将方面的代码插入到应用程序的正常流程中以添加新行为的地方。
Advice:This is an object which includes API invocations to the system wide concerns representing the action to perform at a joinpoint specified by a point.
建议:这是一个对象,其中包括对系统范围内的关注点的 API 调用,这些关注点表示要在由点指定的连接点执行的操作。
Pointcut:A pointcut defines at what joinpoints, the associated Advice should be applied. Advice can be applied at any joinpoint supported by the AOP framework. Of course, you don't want to apply all of your aspects at all of the possible joinpoints. Pointcuts allow you to specify where you want your advice to be applied. Often you specify these pointcuts using explicit class and method names or through regular expressions that define matching class and method name patterns. Some AOP frameworks allow you to create dynamic pointcuts that determine whether to apply advice based on runtime decisions, such as the value of method parameters.
切入点:切入点定义应在哪些连接点处应用相关联的 Advice。可以在 AOP 框架支持的任何连接点应用建议。当然,您不想在所有可能的连接点上应用所有方面。切入点允许您指定要应用建议的位置。通常,您使用显式类和方法名称或通过定义匹配类和方法名称模式的正则表达式来指定这些切入点。一些 AOP 框架允许您创建动态切入点,根据运行时决策(例如方法参数的值)确定是否应用建议。
The following image can help you understand Advice, PointCut, Joinpoints.

下图可以帮助你理解Advice、PointCut、Joinpoints。

Explaination using Restaurant Analogy:Source by @Victor
使用餐厅类比的解释:来源@Victor
When you go out to a restaurant, you look at a menu and see several options to choose from. You can order one or more of any of the items on the menu. But until you actually order them, they are just "opportunities to dine". Once you place the order and the waiter brings it to your table, it's a meal.
当您去餐厅时,您会查看菜单并看到几个可供选择的选项。您可以订购菜单上的一项或多项。但在您真正订购它们之前,它们只是“用餐的机会”。一旦您下订单并且服务员将其带到您的餐桌上,这就是一顿饭。
Joinpoints are options on the menu and Pointcuts are items you select.
连接点是菜单上的选项,切入点是您选择的项目。
A Joinpoint is an opportunity within code for you to apply an aspect...just an opportunity. Once you take that opportunity and select one or more Joinpoints and apply an aspect to them, you've got a Pointcut.
Joinpoint 是代码中的一个机会,您可以应用一个方面……只是一个机会。一旦您抓住这个机会并选择一个或多个连接点并将一个方面应用于它们,您就拥有了一个切入点。
Source Wiki:
来源维基:
A join pointis a point in the control flow of a program where the control flow can arrive via two different paths(IMO : that's why call joint).
Advicedescribes a class of functions which modify other functions
A pointcutis a set of join points.
一个连接点是一个程序,控制流可以通过到达的控制流程的一个点两个不同的路径(IMO:这就是为什么叫关节)。
Advice描述了一类修改其他函数的函数
一个切入点是一组连接点。
回答by Sujay Mumbaraddi
To understand the difference between a join point and pointcut, think of pointcuts as specifying the weaving rules and join points as situations satisfying those rules.
要理解连接点和切入点之间的区别,可以将切入点视为指定编织规则,将连接点视为满足这些规则的情况。
In below example,
在下面的例子中,
@Pointcut("execution(* * getName()")
Pointcut defines rules saying, advice should be applied on getName() method present in any class in any package and joinpoints will be a list of all getName() method present in classes so that advice can be applied on these methods.
切入点定义了规则,建议应该应用于任何包中任何类中的 getName() 方法,连接点将是类中存在的所有 getName() 方法的列表,以便建议可以应用于这些方法。
(In case of Spring, Rule will be applied on managed beans only and advice can be applied to public methods only).
(在 Spring 的情况下,Rule 将仅应用于托管 bean,而通知只能应用于公共方法)。
回答by Krishna
JoinPoints:These are basically places in the actual business logic where you wish to insert some miscellaneous functionality that is necessary but not being part of the actual business logic. Some examples of JoinPints are: method call, method returning normally, method throwing an exception, instantiating an object, referring an object, etc...
JoinPoints:这些基本上是实际业务逻辑中的位置,您希望在其中插入一些必要但不属于实际业务逻辑的杂项功能。JoinPints 的一些例子是:方法调用、方法正常返回、方法抛出异常、实例化对象、引用对象等......
Pointcuts:Pointcuts are something like regular expressions which are used to identify joinpoints. Pontcuts are expressed using "pointcut expression language". Pointcuts are points of execution flow where the cross-cutting concern needs to be applied. There is a difference between Joinpoint and Pointcut; Joinpoints are more general and represents any control flow where we 'may choose to' introduce a cross-cutting concern while pointcuts identifies such joinpoints where 'we want to' introduce a cross-cutting concern.
切入点:切入点类似于正则表达式,用于识别连接点。Pontcuts 使用“切入点表达式语言”表示。切入点是需要应用横切关注点的执行流点。Joinpoint 和 Pointcut 是有区别的;连接点更通用,代表我们“可能选择”引入横切关注点的任何控制流,而切入点标识“我们想要”引入横切关注点的连接点。
回答by Dev S
Layman explanation for somebody who is new to the concepts AOP. This is not exhaustive, but should help in grasping the concepts. If you are already familiar with the basic jargon, you can stop reading now.
对 AOP 概念不熟悉的人的外行解释。这不是详尽无遗的,但应该有助于理解概念。如果您已经熟悉基本术语,现在可以停止阅读。
Assume you have a normal class Employee and you want to do something every time these methods are called.
假设你有一个普通的 Employee 类,你想在每次调用这些方法时做一些事情。
class Employee{
public String getName(int id){....}
private int getID(String name){...}
}
these methods are called JoinPoints. We need a way to identify these methods so that the framework can find the methods, among all the classes.methods it has loaded. So we will write a regular expression to match the signature of these methods. While there is more to it as you will see below, but loosely this regular expression is what defines Pointcut. e.g.
这些方法称为JoinPoints。我们需要一种方法来识别这些方法,以便框架可以在它加载的所有 classes.methods 中找到这些方法。所以我们将编写一个正则表达式来匹配这些方法的签名。正如您将在下面看到的,它还有更多内容,但是这个正则表达式大致定义了Pointcut。例如
* * mypackage.Employee.get*(*)
First * is for modifier public/private/protected/default. Second * is for return type of the method.
第一个 * 用于修饰符 public/private/protected/default。第二个 * 用于方法的返回类型。
But then you also need to tell two more things:
但是你还需要告诉另外两件事:
- Whenshould an action be taken - e.g Before/After the method execution OR on exception
- Whatshould it do when it matches (maybe just print a message)
- 什么时候应该采取行动 - 例如在方法执行之前/之后或出现异常
- 什么它匹配时,应该把它做(也许只是打印一条消息)
The combination of these two is called Advice.
这两者的组合称为Advice。
As you can imagine, you would have to write a function to be able to do #2. So this is how it might look like for the basics.
可以想象,您必须编写一个函数才能执行 #2。所以这就是基础知识的样子。
Note: For clarity, using word REGEXinstead of the * * mypackage.Employee.get*(*). In reality the full expression goes into the definition.
注意:为清楚起见,使用单词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
Once you start using these quite a bit, you might end up specifying many @After/@Before/@Around advices. The repeatedregular expressions will eventually end up making things confusing and difficult to maintain. So what we do, we just give a name to the expression and use it everywhere else in the Aspect class.
一旦你开始大量使用这些,你可能最终会指定许多 @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() {....}
BTW, you would also want to wrap this whole logic in a class, that is called Aspectand you would write a class:
顺便说一句,您还想将整个逻辑包装在一个名为Aspect的类中,然后您将编写一个类:
@Aspect
public class MyAwesomeAspect{....}
To get all these things to work, you would have to tell Spring to parse the classes to read, understand and take action on the @ AOP keywords. One way to do it is specifying the following in the spring config xml file:
为了让所有这些事情都起作用,您必须告诉 Spring 解析类以读取、理解 @AOP 关键字并采取行动。一种方法是在 spring 配置 xml 文件中指定以下内容:
<aop:aspectj-autoproxy>
<aop:aspectj-autoproxy>
回答by kriegaex
Comparing an AOP language like AspectJ to a data query language like SQL, you can think of joinpoints (i.e. all places in your code where you can weave aspect code) as a database table with many rows. A pointcut is like a SELECT stamement which can pick a user-defined subset of rows/joinpoints. The actual code you weave into those selected places is called advice.
将 AOP 语言(如 AspectJ)与数据查询语言(如 SQL)进行比较,您可以将连接点(即代码中可以编织方面代码的所有位置)视为具有多行的数据库表。切入点就像一个 SELECT 语句,它可以选择用户定义的行/连接点子集。您编入这些选定位置的实际代码称为建议。
回答by Amanuel Nega
Definitions
定义
As per the documentation:
根据文档:
Join point:a point during the execution of a program, such as the execution of a method or the handling of an exception.
连接点:程序执行过程中的一个点,例如方法的执行或异常的处理。
You can consider Joint Pointsas events in execution of a program. If you are using Spring AOP, this even is limited to invocation of methods. AspectJ provides more flexibility.
您可以将关节点视为程序执行中的事件。如果您使用的是 Spring AOP,这甚至仅限于方法的调用。AspectJ 提供了更多的灵活性。
But you never handle all events as you don't eat all the food in the menu when you go to a restaurant (I don't know you, you might! But, I certainly don't). So you make a selection of events to handle and what to do with them. Here goes Pointcuts. As per the documentation,
但是您永远不会处理所有事件,因为您去餐厅时不会吃掉菜单上的所有食物(我不认识您,您可能会!但是,我当然不认识)。因此,您可以选择要处理的事件以及如何处理它们。这里是切入点。根据文档,
Pointcut: a predicate that matches join points.
切入点:匹配连接点的谓词。
Then you associate what to do with the Pointcut, there goes Advice. As per the documentation,
然后,您将要做什么与切入点相关联,然后是Advice。根据文档,
Adviceis associated with a pointcutexpression and runs at any join point matched by the pointcut.
Advice与切入点表达式相关联,并在与切入点匹配的任何连接点处运行。
Code
代码
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
}
}
Explanation of Code
代码说明
ExampleBusinessClasswhen proxy-ed, is our target!doYourBusiness()is a possible joint pointSomeAspectis our aspect that crosses in to multiple concerns such assExampleBusinessClasssomePointCut()is a definition of a point cutthat matches our joint pointafterSomePointCut()is an advicethat will be executed after oursomePointCutpoint cutthat matchesdoYourBusiness()joint pointbeforeSomePointCut()is also an advicethat matches allpublicmethod executions. UnlikeafterSomePointCut, this one uses an inline point cut declaration
ExampleBusinessClass代理后,就是我们的目标!doYourBusiness()是一个可能的联合点SomeAspect是我们涉及多个问题的方面,例如ExampleBusinessClasssomePointCut()是与我们的关节点相匹配的切点的定义afterSomePointCut()是在我们的切入点匹配关节点后执行的通知somePointCutdoYourBusiness()beforeSomePointCut()也是匹配所有方法执行的通知public。与afterSomePointCut此不同的是,这个使用了内联切入点声明
You can look at the documentationif you don't believe me. I hope this helps
如果你不相信我,你可以查看文档。我希望这有帮助
回答by Matthew Groves
Both pertain to the "where" of aspect-oriented programming.
两者都与面向方面编程的“位置”有关。
A join point is an individual place where you can execute code with AOP. E.g. "when a method throws an exception".
连接点是您可以使用 AOP 执行代码的单独位置。例如“当一个方法抛出异常时”。
A pointcut is a collection of join points. E.g. "when a method in class Foo throws an exception".
切入点是连接点的集合。例如“当 Foo 类中的方法抛出异常时”。
回答by Vikas Bhardwaj
JoinPoint: Joinpoint are points in your program execution where flow of execution got changed like Exception catching, Calling other method.
JoinPoint:Joinpoint 是程序执行中的点,其中执行流程发生了变化,例如异常捕获、调用其他方法。
PointCut: PointCut are basically those Joinpoints where you can put your advice(or call aspect).
PointCut:PointCut 基本上是那些可以放置建议(或调用方面)的连接点。
So basically PointCuts are the subset of JoinPoints.
所以基本上PointCuts 是 JoinPoints 的子集。
回答by CheckThis
A pointcut is defined on the Aspect - class implementation. The point cut basically refers to the pointcut expression within the advice.
在 Aspect - 类实现上定义了一个切入点。切入点基本上是指通知中的切入点表达式。
For e.g,
例如,
@Before("execution(* app.purchase2.service.impl.*(..))")
public void includeAddOns(RolesAllowed roles) {
..
}
The above means, "includeAddOns" method is called before invoking(due to the @Before advice) any methods(in classes within package "app.purchase2.service.impl")
上面的意思是,在调用(由于@Before 建议)任何方法(在包“app.purchase2.service.impl”中的类中)之前调用“includeAddOns”方法
The whole annotation is called the pointcut
@Before("execution(* app.purchase2.service.impl.*(..))")
整个注解称为切入点
@Before("execution(* app.purchase2.service.impl.*(..))")
Joint point is the actual method invocation, which joined the method in package "app.purchase2.service.impl" to the method in aspect class "includeAddOns()".
联合点是实际的方法调用,将“app.purchase2.service.impl”包中的方法与方面类“includeAddOns()”中的方法连接起来。
You can access properties of the join point with the org.aspectj.lang.JoinPointclass.
您可以使用org.aspectj.lang.JoinPoint该类访问连接点的属性。
回答by yonikawa
I agree with mgroves.. A point cut can be considered as a collection of multiple joint points. Joint point specify the particular location where the advice could be implemented, where as pointcut reflects the list of all joint points.
我同意 mgroves .. 一个切点可以被认为是多个关节点的集合。联合点指定可以实施建议的特定位置,其中切入点反映了所有联合点的列表。

