最近在开发中遇到一个问题,当在Service中定义了一个方法并且切入之后,从Controller里面调用该方法可以实现切入,但是当在同一个Service中实现另一方法并调用改方法时却无法切入。代码类似于:
/**
* Controller 你懂的
*/
public class Ctrl {
public void ctrl() {
......
service.callMethodA();
......
}
}
/**
* 业务实现
*/
public class Service {
/**
* 被Controller调用的方法
* 这个方法调用被切的方法
*/
public void callMethodA() {
......
callMethodB();
......
}
/**
* Aop切入的方法
*/
public void callMethodB() {
......
}
}
/**
* AOP的实现
*/
public class Aspect {
@@AfterReturning("execution(* Service.callMethodB(..))")
public void after() {
Logger.info("after call and do something.");
}
}
总之这样的调用根本不会进去切面,找了很久资料都不知道怎么回事,果然我还是太弱了。后来有幸得问高人,指点说Service中如此调用并非调用的是代理类中的方法,是不会被切进去的。换言之,必须要调用代理类才会被切进去。
那么应该怎么破呢?既然只有调用代理类的方法才能切入,那我们拿到代理类不就好了嘛。尝试性的在IDE里面搜Aop相关的类,一眼就看到一个叫AopContext的东西,看来游戏啊,里面有一个方法叫做currentProxy(),返回一个Object。怎么样都要试一下,果断的把这个object打印出来。报错了……
java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
等等,这个错有点眼熟,之前傻傻找不到问题的时候看过Spring的配置。
<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true" />
把expose-proxy设成true,再跑一次,终于没有报错了,而且打印出了令人欣喜的结果,currentProxy()的结果就是当前Service的代理类,那么事情简单了。修改Service的callMethodA()方法如下:
((Service) AopContext.currentProxy()).callMethodB();
成功了,方法成功的切入进去了,等下只要再把获取代理类的方法独立处理就好了。等等,突然脑洞大开,既然这样可以,那是不是直接applicationContext.getBean()也可以呢?实验过后得到的结果是可行,而且配置中的expose-proxy也不用设置成true。
总算这个问题算是解决了,但是以后在方法调用的时候就需要谨慎了,感觉应该有更好的办法解决这个问题,不知道哪位有更好的办法,能不能告诉我一下下呢?
分享到:
相关推荐
当我们遇到"AOP实现自我调用的事物嵌套问题"时,这通常涉及到Spring框架中的事务管理,特别是自调用方法在事务处理时可能会引发的问题。 首先,让我们理解Spring AOP的事务管理是如何工作的。Spring使用代理模式来...
在Spring AOP(面向切面编程)中,切入点表达式是定义通知(advice)执行时机的关键元素。本文将深入探讨9种不同的切入点表达式及其用法,通过实际的示例代码来帮助理解它们的工作原理。 1. **execute()**: `...
在这个"Castle AOP 对类方法调用的拦截示例Demo"中,我们将深入探讨如何使用Castle框架来实现AOP的拦截功能,并且这个示例是可运行的,这意味着你可以直接运行代码来理解其工作原理。 首先,让我们了解一下Castle....
在.NET中,我们可以通过Attribute来实现AOP的功能,这就是标题中提到的"attribute实现方法调用拦截"。 Attribute的使用通常是通过定义自定义Attribute类,然后在需要的地方应用这些特性。例如,我们可以创建一个`...
`@Pointcut`注解用于定义切入点表达式,匹配特定的方法调用。 3. **切面(Aspect)** 切面是AOP的核心,它封装了关注点的代码。在Spring中,一个切面通常是一个包含通知和切入点的类。切面可以理解为跨越多个对象...
总之,Spring AOP的环绕通知通过切入点匹配方法,提供了对方法调用的全面控制。它不仅可以实现预处理和后处理,还可以根据需要选择是否执行目标方法,是实现复杂业务逻辑和监控的强大工具。结合适当的切入点表达式,...
- 连接点(Join Point):程序执行过程中的特定点,如方法调用、异常处理等。 - 切入点(Pointcut):匹配连接点的规则,定义了哪些连接点会被通知(Advice)拦截。 - 通知(Advice):在特定连接点执行的代码,...
整理的Spring AOP Aspect切入点语法,老师整理的,2018.08.01最新版
拦截器可以在方法调用前、后或抛出异常时执行,而无需修改原始代码。这种方法保持了代码的整洁,但需要对IoC容器有深入理解。 5. **Aspect Frameworks**: 有一些完整的AOP框架,如Spring.NET和NAspect,它们提供...
通过这个库,Spring AOP可以在不改变原有代码结构的情况下,将切面逻辑插入到方法调用的前、后或者异常处理等特定位置,提供了一种强大的代码解耦方式。 2. **aspectjrt.jar**: AspectJ Runtime库是AspectJ运行...
Spring AOP目前只支持方法执行这个连接点,下面我们将详细解析Spring AOP中支持的AspectJ切入点指示符: 1. **execution**:这是最常用的切入点指示符,用于匹配方法执行。它的语法是`execution(modifiers-pattern?...
在上述代码中,我们定义了一个名为`SpringAopLog`的切面类,并通过注解指定了哪些方法会在目标方法执行前后被调用。在`afterReturn`方法中,根据不同的方法名来记录不同的日志信息。 #### 四、总结 通过Spring AOP...
4. **切入点(Pointcut)**:用于匹配连接点的表达式,决定了通知的执行时机,如在特定方法调用时。 5. **引入(Introduction)**:为对象添加新的接口及其实现,如使bean实现IsModified接口。 6. **目标对象(Target ...
本文将深入探讨如何利用AOP的思想,通过方法交换(Method Swizzling)这一“黑魔法”来修改iOS系统类库的方法,实现登录权限的统一管理。 方法交换是Objective-C中的一个特性,但在Swift中也可以通过桥接头文件来...
通过以上示例可以看出,使用 AOP 技术能够方便地截取并修改方法的参数,这在很多场景下非常有用,比如需要根据不同的参数值执行不同的逻辑处理或者在方法调用前后做一些额外的处理工作。掌握这一技巧,不仅能够提高...
1. 联结点(Jointpoint):一个联结点是程序执行过程中的一特定点,例如方法调用、方法执行过程本身、类初始化、对象初始化等。 2. 通知(Advice):在某一个特定的联结点出执行的代码称为通知,例如前置通知...
SpringBoot结合AspectJ实现SpringAOP拦截指定方法的知识点涵盖了多个方面,这包括Spring AOP的基本概念、SpringBoot的应用、切点(Pointcut)与通知(Advice)的定义、自定义注解以及AspectJ的使用。以下是这些知识...
使用 Spring AOP 进行方法耗时监测的好处有以下几点: 1. 代码实现简单,易于维护:使用 Spring AOP 可以将耗时监测的逻辑与业务逻辑进行解耦,避免业务逻辑代码的冗余和代码维护难度的提高。 2. 安全性高:使用 ...
这通常涉及到Spring的代理机制、AOP的切面定义、方法调用上下文以及EL的语法和功能。 Spring AOP是Spring框架的一个重要特性,它允许开发者创建具有横切关注点的模块,如日志记录、事务管理等。这些关注点可以被...