问题描述, 如下Abc定义为一个Bean, b()方法添加@TargetDatasource,定义切面DynamicDataSourceAspect,期望:调用a()方法,b()方法上的AOP拦截能生效。实际不生效。

@Service

public class Abc {

public void a(){
b();
} @TargetDatasource(value=abc)
public void b(){
}
}

AOP代码:

@Order(-1)
@Component
@Slf4j
@Aspect
public class DynamicDataSourceAspect { /**
* set data source value.
*/
@Before(value = "@annotation(targetDataSource)", argNames = "targetDataSource")
public void setDataSource(TargetDataSource targetDataSource) {
if (targetDataSource != null && targetDataSource.value() != null) {
log.info("Databse value: {}", targetDataSource.value());
DynamicDataSourceHolder.set(targetDataSource.value());
}
} /**
* clear data source value.
*/
@After(value = "@annotation(targetDataSource)", argNames = "targetDataSource")
public void clearDataSource(TargetDataSource targetDataSource) {
DynamicDataSourceHolder.clear();
}
}

问题分析:

我们都知道Spring aop有两种实现方式,基于Interface生成代理和cglib生成代理。上面的例子中,当调用a()方法时,调用者拿到的是Abc的代理类,即增强类。如果a()方法上有@TargetDatasource注解,拦截会生效。然而,在a()方法里调用b(),b方法上的拦截不会生效。原因是因为a()调用b(), 用的是b()方法的目标类,而不是代理类,所以拦截不生效。

解决方法:

1. 重构代码, 把b()方法移到一个Bean里面。

2. 调整a()方法如下:

@Service

public class Abc {

public void a(){
((Abc)AopContext.currentProxy()).b();
} @TargetDatasource(value=abc)
public void b(){
}
}

Sping 官方解释 - https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop

Spring 嵌套方法AOP不生效问题的更多相关文章

  1. 使用spring框架进行aop编程实现方法调用前日志输出

    aop编程 之使用spring框架实现方法调用前日志输出 使用spring框架实现AOP编程首先需要搭建spring框架环境: 使用Spring框架实现AOP工程编程之后,不需要我们去写代理工厂了,工 ...

  2. Spring基础系列--AOP织入逻辑跟踪

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9619910.html 其实在之前的源码解读里面,关于织入的部分并没有说清楚,那些前置.后 ...

  3. Spring系列之AOP的原理及手动实现

    目录 Spring系列之IOC的原理及手动实现 Spring系列之DI的原理及手动实现 引入 到目前为止,我们已经完成了简易的IOC和DI的功能,虽然相比如Spring来说肯定是非常简陋的,但是毕竟我 ...

  4. Spring基础系列-AOP源码分析

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9560803.html 一.概述 Spring的两大特性:IOC和AOP. AOP是面向切 ...

  5. spring IOC 和AOP 方面

    spring 的2大核心 是Ioc 和 aop  spring的依赖注入:在程序运行期间,由外部容器动态的将依赖对象注入到组件中  IOC: 实例化spring容器的二种方法 第一种:在类路径下寻找配 ...

  6. Spring IOC 和 AOP概述

    IoC(控制反转,(Inversion of Control):本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫控制反转,即交给了IoC容器,Spring的IoC容器主要使用DI方 ...

  7. 4.spring:@Profile,AOP

    Profile: 可以根据当前的环境,动态激活和切换一系列的组件功能 指定组件在那个环境下才能被注册到容器中,不指定任何环境下都能注册到 1.加了环境标识的bean只有环境激活的时候才能注册到容器中 ...

  8. Spring事务管理—aop:pointcut expression 常见切入点表达式及事务说明

    Spring事务管理—aop:pointcut expression 常见切入点表达式及事物说明 例: <aop:config>  <aop:pointcut expression= ...

  9. Spring笔记:AOP基础

    Spring笔记:AOP基础 AOP 引入AOP 面向对象的开发过程中,我们对软件开发进行抽象.分割成各个模块或对象.例如,我们对API抽象成三个模块,Controller.Service.Comma ...

随机推荐

  1. 12C新特性--Application Continuity

    Application Continuity特性可以在中断后恢复受影响的数据库会话的任务,从而让终端用户和应用程序感觉不到中断的发生.Application Continuity执行恢复的过程是在应用 ...

  2. primary库新增数据文件后,standby库无法创建文件并终止数据同步

    主库是RAC环境,使用asm存放数据文件,备库是操作系统本地文件系统存放数据文件.在主库执行以下操作: SQL> alter tablespace ysdv add datafile '+dat ...

  3. arcgismanager登陆信息不对

    arcgis版本:arcgis10 安装arcgis server后(java版的win764位系统),发现arcgis管理器登陆界面(http://localhost:8099/arcgismana ...

  4. Effective Java 第三版——52. 明智而审慎地使用重载

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  5. 目标检测比赛---Google AI Open Images - Object Detection Track

    https://www.kaggle.com/c/google-ai-open-images-object-detection-track#Evaluation Submissions are eva ...

  6. 【Python】Python的安装与个人使用记录

    下载 从官网上下载,目前,最新版是Python3,基于项目需求,我们使用的是Python2. 我是在CentOS上安装,下载的是Python-2.7.9.tgz. 安装 tar -zxvf Pytho ...

  7. js实现cookie跨域功能

    /** * 设置cookie方法 * @param {string} name cookie键值 * @return {*} 返回cookie值 */ function setCookie_log(c ...

  8. Numpy数组与PIL Image转换

    引用于这个博客

  9. Java8学习笔记(五)--Stream API详解[转]

    为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...

  10. Service 中的 onStart 和 onStartCommand

    在自定义的service中,写了onStart和onStartCommand, public class HttpWebService extends Service { @Override publ ...