问题描述, 如下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. wamp设置实现本机IP或者局域网访问

    在 httpd.conf 中查找 Allow from 127.0.0.1 Order Deny,Allow Deny from all Allow from 127.0.0.1 在此下面加上 All ...

  2. HTML5中的History对象

    HTML5标准之前 基本操作 1.forward(number) 加载histroy列表中的下一个URL 2.back(number) 加载histroy列表中的上一个URL 3.go(number) ...

  3. SNF快速开发平台MVC-富文本控件集成了百度开源项目editor

    一.效果如下: 二.在框架当中调用代码如下: 1.在js里配置如下: <script type="text/javascript"> var viewModel =fu ...

  4. 使用vw做移动端页面的适配

    Flexible到今天也有几年的历史了,解救了很多同学针对于H5页面布局的适配问题.而这套方案也相对而言是一个较为成熟的方案.简单的回忆一下,当初为了能让页面更好的适配各种不同的终端,通过Hack手段 ...

  5. 运行第一个Docker容器-Docker for Web Developers(1)

    1. Docker介绍 Docker由dotCloud公司发起的一个内部项目,后来Docker火了,dotCloud公司改名为Docker了: Docker使用了Go语言开发,基于 Linux 内核的 ...

  6. Java两种核心机制

    1.Java虚拟机 2.垃圾回收

  7. kafka性能测试1.0.0

    kafka提供工具kafka-producer-perf-test.sh用以压测, 参数 说明 messages 生产者发送总的消息数量 message-size 每条消息大小 batch-size ...

  8. gSOAP 初体验

    安装 由于本人使用的是 Mac OS 系统,故以 Mac OS 为例说明如何安装 gSOAP. 1)下载 gSOAP 可以在 https://sourceforge.net/projects/gsoa ...

  9. 如何查看WAS生成的Snap.***.trc文件

    WAS发生heapdump时随之还产生了javacore和Snap.***.trc文件 Snap.***.trc文件无法直接查看,需要对其进行格式化,就算用文本编辑器打开看见的也是有很多乱码 跟踪格式 ...

  10. mysql 分组查询的结果当成临时表 在求最大值

    select avg(data1) as a from temp WHERE YEAR(mdate)= 2018 and MONTH(mdate)=03 and day(mdate)=25 GROUP ...