首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么JoinPoint或ProceedingJoinPoint的对象可以调用方法?

基础概念

JoinPointProceedingJoinPoint 是 Spring AOP(面向切面编程)中的两个核心接口。它们用于在方法执行前后插入额外的逻辑(如日志记录、事务管理、权限检查等)。

  • JoinPoint:表示程序执行过程中的一个点,通常是一个方法的执行点。它提供了访问当前连接点的方法和目标对象的信息。
  • ProceedingJoinPoint:继承自 JoinPoint,它允许在切面中控制目标方法的执行。通过调用 proceed() 方法,可以继续执行目标方法。

相关优势

  1. 解耦:通过 AOP,可以将横切关注点(如日志记录、事务管理)从业务逻辑中分离出来,使代码更加清晰和模块化。
  2. 可维护性:横切关注点的变化不会影响到业务逻辑代码,提高了代码的可维护性。
  3. 可重用性:切面可以跨多个模块或项目重用,减少了重复代码。

类型

  • 静态切面:在编译时织入,通常通过注解或 XML 配置实现。
  • 动态切面:在运行时织入,通常通过代理机制实现。

应用场景

  • 日志记录:在方法执行前后记录日志。
  • 事务管理:在方法执行前后开启和提交事务。
  • 权限检查:在执行方法前检查用户权限。
  • 性能监控:记录方法的执行时间。

为什么 JoinPointProceedingJoinPoint 的对象可以调用方法?

JoinPointProceedingJoinPoint 是 Spring AOP 框架提供的接口,它们封装了目标方法的信息和调用上下文。通过这些接口,可以在切面中访问和操作目标方法。

  • JoinPoint:提供了访问目标对象和方法签名等信息的方法,如 getTarget()getSignature() 等。
  • ProceedingJoinPoint:继承自 JoinPoint,并提供了 proceed() 方法,该方法允许切面控制目标方法的执行。

示例代码

以下是一个简单的示例,展示了如何在切面中使用 ProceedingJoinPoint 来控制目标方法的执行:

代码语言:txt
复制
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    @Around("execution(* com.example.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object proceed = joinPoint.proceed();

        long executionTime = System.currentTimeMillis() - start;

        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
        return proceed;
    }
}

参考链接

通过上述解释和示例代码,你应该能够理解 JoinPointProceedingJoinPoint 的基本概念、优势、类型、应用场景以及它们如何调用方法。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

django小技巧之html模板中调用对象属性对象方法

url(r’^$’,views.index,name=’index’), ] 以上基本配置完成,下面演示在模板中调用对象方法: 定义模型类: 为了不用迁移,定义模型类要和test2数据库结构一样...–调用对象属性– {{hero.showname}}<!–调用对象方法,但不能给方法传递参数– <!...–注释 #点号解析顺序: #1.先把hero作为字典,hname为键查找 #2.再把hero作为对象,hname为属性方法查找 #3.最后把hero作为列表,hname为索引查找 — <...pymysql pymysql.install_as_MySQLdb() 再次启动web服务成功;浏览器访问:http://192.168.255.70:8000/ 完成验收在html模板文件中调用对象属性和对象方法...模板变量如何传递给外部js调用方法小结 python Django模板使用方法 编写自定义Django模板加载器简单示例 python Django模板使用方法(图文)

3.3K21

写了个牛逼日志切面,甩锅更方便了!

入参出错导致接口调试失败问题在联调中出现很多次,因此就想写一个请求日志切面把入参信息打印一下,同时协议层调用服务层接口名称对不上也出现了几次,通过请求日志切面就可以知道上层是否有没有发起调用,方便前后端甩锅还能拿出证据...().getDeclaringTypeName(), joinPoint.getSignature().getName()); } 在进入Controller方法前,打印出调用方IP、请求URL、HTTP...请求类型、调用方法名 使用@Around打印进入控制层入参 @Around("requestServer()") public Object doAround(ProceedingJoinPoint...,因此需要手动拼接一下参数名,同时对文件对象进行了特殊处理,只需获取文件名即可 @After方法调用后执行 @After("requestServer()") public void doAfter(JoinPoint...,再序列化打印对象 打印序列化对象结果而不是直接打印对象是因为序列化有更直观、更清晰,同时可以借助在线解析工具对结果进行解析 ?

41230
  • 写了个牛逼日志切面,甩锅更方便了!

    ().getDeclaringTypeName(), joinPoint.getSignature().getName()); } 在进入 Controller 方法前,打印出调用方 IP...、请求 URL、HTTP 请求类型、调用方法名 使用 @Around 打印进入控制层入参 @Around("requestServer()") public Object doAround(ProceedingJoinPoint...,因此需要手动拼接一下参数名,同时对文件对象进行了特殊处理,只需获取文件名即可 @After 方法调用后执行 @After("requestServer()") public void doAfter...,再序列化打印对象 打印序列化对象结果而不是直接打印对象是因为序列化有更直观、更清晰,同时可以借助在线解析工具对结果进行解析 ?...推荐使用 log4j2,为什么推荐使用 log4j2 可以看下这篇文章:日志框架,选择 Logback Or Log4j2? log4j2 也是可以配合 MDC 一起使用 ?

    1.7K31

    为什么start方法不能重复调用?而run方法可以

    方法 thread2.start(); } 以上程序执行结果如下: 从上述结果可以看出,二者调用之后执行效果都是一样,都可以成功执行任务。...start 方法 thread2.start(); } 以上程序执行结果如下: 从上述结果我们可以看出:当调用 run 方法时,其实是调用当前主程序 main 来执行方法;而调用...区别3 因为 run 方法是普通方法,而普通方法可以被多次调用,所以 run 方法可以调用多次;而 start 方法是创建新线程来执行任务,因为线程只能被创建一次,所以它们第三个区别是:run...方法可以调用多次,而 start 方法只能被调用一次。...为什么start不能被重复调用

    71210

    写了个牛逼日志切面,甩锅更方便了!

    ().getDeclaringTypeName(), joinPoint.getSignature().getName()); } 在进入 Controller 方法前,打印出调用方 IP...、请求 URL、HTTP 请求类型、调用方法名 使用 @Around 打印进入控制层入参 @Around("requestServer()") public Object doAround(ProceedingJoinPoint...,因此需要手动拼接一下参数名,同时对文件对象进行了特殊处理,只需获取文件名即可 @After 方法调用后执行 @After("requestServer()") public void doAfter...写更健壮代码 解决日志串行问题只要将多行打印信息合并为一行就可以了,因此构造一个对象 RequestInfo.java @Data public class RequestInfo {...,再序列化打印对象 打印序列化对象结果而不是直接打印对象是因为序列化有更直观、更清晰,同时可以借助在线解析工具对结果进行解析 是不是还不错 在解决高并发下请求串行问题同时添加了对异常请求信息打印,

    59030

    Spring AOP到底是什么?

    利用容器管理所有的框架、业务对象,我们可以做到: 无侵入调整对象关系 无侵入地随时调整对象属性 实现对象替换 这使得框架开发者在后续实现一些扩展就很容易。 什么是AOP?...例如,一个简单缓存aspect可以返回一个值从缓存(如果它有)调用procedd如果它没有。请注意,可以多次调用procedd,或者根本不在around advice主体内调用,这都是合法。...在通知方法体中,调用 proceed() 会导致基础方法运行。 proceed() 也可以在Object[]中传递。数组中值在进行时用作方法执行参数。...Access to the Current JoinPoint 任何通知方法都可能声明类型org.aspectj.lang.JoinPoint 参数(请注意,围绕建议需要申报类型’继续JoinPoint...JoinPoint 接口提供了许多有用方法: getArgs() 返回方法参数 getThis() 返回代理对象 getTarget() 返回目标对象 getSignature() Returns

    42220

    业务系统 hystrix 实际应用

    第三方客户就是一个“黑匣子”,其中实施细节被隐藏,并且可以随时更改,网络资源配置对于每个客户端库都是不同,通常难以监视和 更改。 通过故障包括: 网络连接失败降级。 服务和服务器失败变慢。...新服务部署会改变行为性能特征。 客户端库有错误。 所有这些都代表需要隔离和管理故障和延迟,以便单个故障依赖关系不能导致整个应用程序系统故障。...主要有以下几点: 合理分配资源,把给资源分配控制权交给用户,某一个依赖故障不会影响到其他依赖调用,访问资源也不受影响。 可以方便指定调用策略,比如超时异常,熔断处理。...当一个失败依赖再次变成可用时,线程池将清理,并立即恢复可用,而不是一个长时间恢复。 可以完全模拟异步调用,方便异步编程。 使用线程池,可以有效进行实时监控、统计和封装。...了,为什么呢?

    24410

    Spring-AOP思想

    [] interfaces = new Class[]{ArithmeticCalculator.class}; //当调用代理对象其中方法时,该执行代码 InvocationHandler...如果某方法调用前,调用后,方法抛出异常后。连接点由两个 信息确定:方法表示程序执行点;相对点表示方位。 切点: 每个类都拥有多个连接点。AOP通过切点定位到特定连接点。...*(int, int))") 1 可以在声明通知方法中声明一个类型为JoinPoint参数,然后就能访问链接细节,如方法名称和参数。...+ " end with: " + result); } /** * 在方法出现异常时,会执行代码 * 可以访问到异常对象,且可以指定出现特定异常时在执行通知代码...类型参数 * 环绕通知类似于动态代理全过程:ProceedingJoinPoint类型参数可以决定是否执行目标方法 * 环绕通知必须有返回值,且返回值为目标方法返回值

    26520

    【Java】已解决:org.springframework.aop.AopInvocationException

    该错误通常发生在尝试调用被代理方法时,无法正确处理方法调用方法本身存在问题。 问题场景 假设我们在开发一个Spring Boot项目时,使用AOP来记录方法执行时间。...类型错误 如果在切面代码中未正确处理返回值类型,可能导致AopInvocationException错误。例如,如果代理对象方法返回类型与实际方法返回类型不匹配,则可能引发该异常。 2....数据类型不匹配 切面中方法调用过程中,如果参数类型不匹配,或者在拦截方法时未正确处理参数类型,也可能引发此异常。 3....五、注意事项 正确调用ProceedingJoinPoint.proceed()方法:在使用AOP时,确保在切面中正确调用joinPoint.proceed()方法,以执行被代理方法。...检查方法返回类型:确保切面中返回类型与目标方法返回类型一致,以避免类型不匹配问题。 注意方法访问修饰符:确保目标方法访问修饰符允许切面访问和调用

    8610

    AOP设计与实现

    前置切面,在方法执行之前被调用 Around 环绕切面,可以在切面内部执行具体方法,因此可以在具体方法执行前后添加自己需要东西 After 后置切面,在方法执行完成之后被调用 基本功能 上面基础三中切面支持...一个方法可以被多个切面拦截(即一个方法可以同时对应多个Before,After,Around切面) 切面执行先后顺序(一般而言,before优先around优先after) 被切方法只能执行一遍...辅助类 实现AOP,肯定少不了代理,因此我们需要定义一个类,来包装执行方法相关信息,用于传递给各个切面类中方法 JoinPoint 包含实际对象,执行方法,参数 @Data public class...方法中,可以查询被切方法基本信息(如方法签名,参数回信息,返回对象等) @Data public class BeforeProcess implements IAopProcess { /...,不过只有第一个around切面中是真的执行了具体方法调用,后面的around切面都是直接使用了第一个around执行后结果(直接看ProceedingJoinPoint源码就知道了) AroundProcess

    91970

    Spring5系列(十一) | 基于注解AOP编程

    原因就是login方法是用this调用,获得并不是代理对象所以不会执行对应额外功能。相当于是直接调用了原始类中方法。...如果此时让login方法也带上额外功能该怎么办呢,就是我们要通过代理对象调用login方法。...这个时候就可以用我们之前文章中讲到ApplicationContextAware来实现,把工厂注入进来,通过工厂去获取对象调用可以了。...login方法,---核心功能,切面功能不执行 // 设计目的是: 调用代理对象login方法 this.login("abc", "123456"); //获取代理对象...,只有最外层方法才是加入额外功能,内部方法通过普通方式调用,都是调用原始方法,如果想让内层方法调用代理对象方法,就要通过ApplicationContextAware接口,获取现有工厂 ,进而获得代理对象

    25210

    Spring5深入浅出篇:基于注解实现AOP

    Spring5深入浅出篇:基于注解实现AOP基于注解AOP编程开发步骤原始对象 额外功能 切⼊点 组装切⾯ 可以发现其实1,2,3最终目的就是为了去组装切面,其实这里和我们传统开发aop步骤是一样...{ //这里通过注解方式定义切入点表达式 @Around("execution(* login(..))") public Object arround(ProceedingJoinPoint joinPoint...方式来代表原始方法执行,而是ProceedingJoinPoint Object ret = joinPoint.proceed(); return ret; } //可以明显发现这里写了重复代码...MethodInvocation方式来代表原始方法执行,而是ProceedingJoinPoint Object ret = joinPoint.proceed(); return ret; } }...JDK 通过实现接⼝ 做新实现类⽅式 创建代理对象2. Cglib通过继承⽗类 做新⼦类 创建代理对象默认情况 AOP编程 底层应⽤JDK动态代理创建⽅式如果切换Cglib 1.

    15510

    Spring AOP到底是什么?

    利用容器管理所有的框架、业务对象,我们可以做到: 无侵入调整对象关系 无侵入地随时调整对象属性 实现对象替换 这使得框架开发者在后续实现一些扩展就很容易。 什么是AOP?...例如,一个简单缓存aspect可以返回一个值从缓存(如果它有)调用procedd如果它没有。请注意,可以多次调用procedd,或者根本不在around advice主体内调用,这都是合法。...在通知方法体中,调用 proceed() 会导致基础方法运行。 proceed() 也可以在Object[]中传递。数组中值在进行时用作方法执行参数。...Access to the Current JoinPoint 任何通知方法都可能声明类型org.aspectj.lang.JoinPoint 参数(请注意,围绕建议需要申报类型’继续JoinPoint...JoinPoint 接口提供了许多有用方法: getArgs() 返回方法参数 getThis() 返回代理对象 getTarget() 返回目标对象 getSignature() Returns

    15320

    调用内部私有方法N种方法

    非公开类型或者方法被“隐藏”在程序集内部,本就不希望从外部访问,但是有时候调用一个内部或者私有方法可能是唯一“救命稻草”,这篇文章列出了几种具体实现方式。...以如下这个Foobar类型为例,它具有一个内部属性InternalValue,我们来看看有多少种方式可以从外部获取一个Foobar对象InternalValue属性值。...由于返回值实际上是通过InternalValue属性Get方法获得,而表示方法MethodInfo类型具有一个CreateDelegate方法,我们可以采用如下方式利用InternalValue...在如下代码中,我们创建了一个DynamicMethod类型表示动态方法,以IL Emit方式利用IL指令Call完成了针对InternalValue属性Get方法调用。...(calli) 了解IL朋友应该知道,方法调用涉及IL治理有三个(Call、Callvir和Calli)。

    20420

    谈谈对Android上AspectJ使用想法

    ,而且原有的功能并不知道你已经添加了新功能;AOP就是在某一个类方法执行前后打个标记,声明在执行到这里之前要先执行什么,执行完这里之后要接着执行什么。...工作原理.png 首先谈谈AspectJ相关几个概念点 Join Points(连接点) Join Points可以看作是程序运行时一个执行点,比如:一个函数调用可以看作是个Join Points...Join Points都是我们关心,Pointcuts就是提供一种使得开发者能够选择自己需要JoinPoints方法;或者说是程序中可能作为代码注入目标的特定点,例如一个方法调用或者方法入口。...()可以获取到调用方法对象 if (proceedingJoinPoint.getThis() instanceof Context) { mContext = (Context)...proceedingJoinPoint.getThis(); } else { //proceedingJoinPoint.getArgs()可以获取到方法所有参数 for

    1.7K40

    Java开发框架之Spring AOP知识总结

    这样一来横切关注点就被模块化到特殊对象(切面)里。 2.为什么需要AOP? 越来越多非业务需求(日志和验证等)加入后, 原有的业务方法急剧膨胀....上述问题解决方法就是使用动态代理,代理设计模式原理是使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象调用都要通过代理....): 向目标对象应用通知之后创建对象; 连接点(Joinpoint):程序执行某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。...甚至可以控制是否执行连接点。对于环绕通知来说, 连接点参数类型必须是 ProceedingJoinPoint可以决定是否执行目标方法。...它是 JoinPoint 子接口, 允许控制何时执行, 是否执行连接点。在环绕通知中需要明确调用 ProceedingJoinPoint proceed() 方法来执行被代理方法.

    57020
    领券