当前位置: 首页 > 编程日记 > 正文

Spring AOP无法拦截内部方法调用-- expose-proxy=true用法

假设一个接口里面有两个方法:

package demo.long;public interface CustomerService {  public void doSomething1();  public void doSomething2();  
}

接口实现类如下:

package demo.long.impl;import demo.long.CustomerService; public class CustomerServiceImpl implements CustomerService {  public void doSomething1() {  System.out.println("CustomerServiceImpl.doSomething1()");  doSomething2();  }  public void doSomething2() {  System.out.println("CustomerServiceImpl.doSomething2()");  }  }  

现在我需要在CustomerService接口的每个方法被调用时都在方法前执行一些逻辑,所以需要配置一个拦截器:

package demo.long;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect
public class CustomerServiceInterceptor {@Before("execution(* demo.long..*.*(..))")public void doBefore() {System.out.println("do some important things before..."); }
}

把Bean加到Spring配置中

<aop:aspectj-autoproxy /><bean id="customerService" class="demo.long.impl.CustomerServiceImpl" />
<bean id="customerServiceInterceptor" class="demo.long.CustomerServiceInterceptor" />

如果现在外部对象调用CustomerService的doSomething1()方法的时候,会发现只有doSomething1()方法执行前打印了“do some important things before...”,而doSomething1()内部调用doSomething2()时并没有打印上述内容;外部对象单独调用doSomething2()时会打印上述内容。

public class CustomerServiceTest {@AutowiredICustomerService customerService;@Testpublic void testAOP() {customerService.doSomething1();}
}

原因分析

拦截器的实现原理就是动态代理,实现AOP机制。Spring 的代理实现有两种:一是基于 JDK Dynamic Proxy 技术而实现的;二是基于 CGLIB 技术而实现的。如果目标对象实现了接口,在默认情况下Spring会采用JDK的动态代理实现AOP,CustomerServerImpl正是这种情况。

JDK动态代理生成的CustomerServiceImpl的代理类大致如下:

public class CustomerServiceProxy implements CustomerService {  private CustomerService customerService;  public void setCustomerService(CustomerService customerService) {  this.customerService = customerService;  }  public void doSomething1() {  doBefore();  customerService.doSomething1();  }  public void doSomething2() {  doBefore();  customerService.doSomething2();  }  private void doBefore() {  // 例如,可以在此处开启事务或记录日志System.out.println("do some important things before...");  }  }  

客户端程序使用代理类对象去调用业务逻辑:

public class TestProxy {  public static void main(String[] args) {  // 创建代理目标对象// 对于Spring来说,这一工作是由Spring容器完成的。  CustomerService serviceProxyTarget = new CustomerServiceImpl();  // 创建代理对象// 对于Spring来说,这一工作也是由Spring容器完成的。 CustomerServiceProxy serviceProxy = new CustomerServiceProxy();  serviceProxy.setCustomerService(serviceProxyTarget);  CustomerService serviceBean = (CustomerService) serviceProxy;  // 调用业务逻辑操作  
        serviceBean.doSomething1();  }  
}  

执行main方法,发现doSomething1()中调用doSomething2()方法的时候并未去执行CustomerServiceProxy类的doBefore()方法。其实doSomething2()等同于this.doSomething2(),在CustomerServiceImpl类中this关键字表示的是当前这个CustomerServiceImpl类的实例,所以程序会去执行CustomerServiceImpl对象中的doSomething2()方法,而不会去执行CustomerServiceProxy类对象中的 doSomething2()方法。

在使用Spring AOP的时候,我们从IOC容器中获取的Bean对象其实都是代理对象,而不是那些Bean对象本身,由于this关键字引用的并不是该Service Bean对象的代理对象,而是其本身,因此Spring AOP是不能拦截到这些被嵌套调用的方法的。

解决方案

  1. 修改类,不要出现“自调用”的情况:这是Spring文档中推荐的“最佳”方案;
  2. 若一定要使用“自调用”,那么this.doSomething2()替换为:((CustomerService) AopContext.currentProxy()).doSomething2();此时需要修改spring的aop配置:
<aop:aspectj-autoproxy expose-proxy="true" />

 转自:https://www.jianshu.com/p/6534945eb3b5

转载于:https://www.cnblogs.com/ithfm/p/10281355.html

相关文章:

HDD工作原理 导图

以上导图介绍了我们使用的 (HDD)机械硬盘的基本构造以及核心工作原理&#xff0c;对于大家扫盲有所帮助 参考文档&#xff1a; https://blog.csdn.net/yizhaoxin/article/details/53615740

计算机专业口号16字,计算机专业16口号

计算机专业&#xff0c;我们学校要弄运动会&#xff0c;求霸气口号计算机系齐心协力!! 力争上游!! 永不言弃!! 心系X班&#xff0c;合作无间&#xff0c;力斩群敌&#xff0c;舍我其谁 . 凌云赛场,斗志昂扬.文韬武略,笑傲群芳.利剑出鞘,倒海翻江 友谊第一、比赛第二 赛出风格、…

检测实现OpenCV2.4.4实现Shi-Tomasi角点检测(goodFeaturesToTrack)

最近研究检测实现&#xff0c;稍微总结一下&#xff0c;以后继续补充&#xff1a; #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> #include <stdlib.h>using…

autoLayout

第一次使用自动布局&#xff0c;记录下来,或许以后用第三方用不到这个&#xff0c;但是第一次接触VFL语言。 一个按钮&#xff0c;不论横竖屏&#xff0c;都要在屏幕底部。 UIView *bottomV [[UIView alloc]init]; bottomV.backgroundColor [UIColor whiteColor];[bottomV se…

复制图片的一部分

// 复制图片的一部分 procedure TForm1.Button1Click(Sender: TObject);var Bitmap: TBitmap; MyRect: TRect;begin MyRect : Rect(10,10,100,100);//定义复制范围 Bitmap : TBitmap.Create; //生成Bitmap对象 Bitmap.LoadFromFile(1.bmp); Form1.Canvas.BrushCopy(MyRec…

计算机rsnge指令,计算机二级office Excel 函数复习重点

原标题&#xff1a;计算机二级office Excel 函数复习重点计算机二级来袭&#xff01;近期&#xff0c;计算机二级考试即将开始&#xff0c;小编在这里为大家奉上众多难点中的一个考点的详解——《excel函数的应用》&#xff0c;希望能为您的考试锦上添花。常用的逻辑函数1、求和…

tag标签[置顶] 高级NFC

最近朋友几篇文章分析了改tag标签的文章. 关联文章的地址 文章译自&#xff1a;Advanced NFC 本文档分析了高级NFC&#xff0c;如与各种标签技术协作&#xff0c;NFC标签写入和前台调度&#xff0c;它答应应用程序在前台处置的intent&#xff0c;即使当其他应用程序过滤器雷同…

python中类的约束和限制对象添加属性

通过__slots__限制对象可添加的属性 class A:__slots__ [a, b]passa1 A() a1.a 10 print(a1.a) a1.c 0 # 只能添加a&#xff0c;b属性添加其他属性就报错 没有约束 class Alipay:def pay(self, money):print(此次消费%s % money)class QQpay:def pay(self, money):print…

CEPH核心理论 相关导图(持续更新)

围绕分布式存储(ceph)绘制的技能图谱可参考分布式存储ceph 技能图谱 相关的原始编辑文件可以从github-mindMapping下载 如有缺失、不足之处欢迎指正 CEPH架构 关于系统架构&#xff0c;这里主要是将CEPH融入操作系统架构之中 且是根据L版本进行绘制的 关于文件系统 &#xff1…

Newtonsoft.Json文件错误

今天&#xff0c;在一个项目中使用signalR&#xff0c;由于项目框架是.net 4.0,所以用signalR1.0版本&#xff0c;signalR使用需要newtonsoft.Json文件&#xff0c;它把原 newtonsoft.Json文件覆盖了&#xff0c;所以程序运行时出现如下错误&#xff1a; “ 未能加载文件或程…

提花原理与计算机,电脑提花袜的设计原理与方法:提花女袜

全电脑单针筒袜机生产提花袜&#xff0c;运用计算机辅助设计系统进行袜子的花型图案及编织程序设计。文章介绍了提花袜的组织结构设计与提花编织原理及花型设计与编辑的方法。   Jacquard hosiery has been produced on the computerized hosiery machine with single cylind…

linux网络虚拟化

地址&#xff1a;http://blog.kghost.info/2013/03/01/linux-network-emulator/安装ip netns命令&#xff1a;#yum instal -y *netns*另附一个地址&#xff1a;http://crpppc19.epfl.ch/cgi-bin/man/man2html?ip-netns8转载于:https://blog.51cto.com/kernal/1540612

Linux内存管理:bufferCache和PageCache

参考文档&#xff1a; https://zhuanlan.zhihu.com/p/42364591 https://zhuanlan.zhihu.com/p/32354613 《深入理解Linux 内核》

mfc 开启指定服务器,用MFC实现消息的发送和接收(含服务器)

《用MFC实现消息的发送和接收(含服务器)》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《用MFC实现消息的发送和接收(含服务器)(33页珍藏版)》请在人人文库网上搜索。1、精品好资料学习推荐新建WClient工程基于对话框OK&#xff0c;直接Finish界面制作我们需要三个按…

Web Api学习一

接触WebApi读的第一篇文章&#xff1a; ASP.NET Web API&#xff08;一&#xff09;&#xff1a;使用初探&#xff0c;GET和POST数据 实践过程中&#xff0c;用的Fiddler模拟Post请求时收到的对象总是为空null 解决&#xff1a;将文章中的内容改为了如下&#xff1a; User-Agen…

HTML5十五大新特性

HTML5想必大家都很熟悉了。然而&#xff0c;你能准确地说出HTML5带来了哪些新特性吗&#xff1f;本文总结了HTML5带来的15项你必须知道的新特性。一起来看下&#xff1a;1.新的文档类型 (New Doctype)目前许多网页还在使用XHTML 1.0 并且要在第一行像这样声明文档类型&#xf…

[THUWC2017]随机二分图

题目大意 给一张二分图&#xff0c;有左部点和右部点。 有三种边&#xff0c;第一种是直接从左部点连向右部点&#xff0c;出现概率为50%。 第二种边一组里有两条边&#xff0c;这两条边同时出现或者不出现&#xff0c;概率都是50%。 第三种边一组里有两条边&#xff0c;这两条…

Eclipse问题集锦

1、SDK版本过低的问题。 现象&#xff1a; 更新SDK后&#xff0c;每次进入Eclipse&#xff0c;都会提示说需要23.0.0版本的SDK&#xff0c;当前的22.6.0版本的SDK版本过低&#xff1b;然而&#xff0c;确认更新后&#xff0c;结果却是说没有任何更新的东东。 解决办法&#xff…

渥太华大学计算机硕士课程,渥太华大学计算机工程专业解析

本课程以扎实的传统工程技术为基础&#xff0c;涵盖计算机软硬件设计的多个不同方面&#xff0c;并可对基于微处理器的系统、计算机体系结构、编程概念、实时操作系统、软件工程和机器人技术进行更专业的研究。这个项目提供了多种职业发展途径。强制一年级的课程:化学原理gng11…

博弈最高位POJ 1704(Georgia and Bob-Nim博弈)

新手发帖&#xff0c;很多方面都是刚入门&#xff0c;有错误的地方请大家见谅&#xff0c;欢迎批评指正 Georgia and BobTime Limit: 1000MS Memory Limit: 10000KTotal Submissions: 6341 Accepted: 1826Description Georgia and Bob decide to play a self-invented game. Th…

用Python深入理解跳跃表原理及实现

最近看 Redis 的实现原理&#xff0c;其中讲到 Redis 中的有序数据结构是通过跳跃表来进行实现的。第一次听说跳跃表的概念&#xff0c;感到比较新奇&#xff0c;所以查了不少资料。其中&#xff0c;网上有部分文章是按照如下方式描述跳跃表的&#xff1a; 这种描述便于理解&am…

Linux进程管理:进程状态和CPU平均负载

常见的linux进程状态如下&#xff1a; 关于源文件xmid&#xff0c;可以从Mind-Mapping获取 这里借助进程状态来描述一下linux系统中的平均负载的概念 当我们感觉到系统变慢时&#xff0c;通常通过top和uptime命令来了解系统的负载情况 [rootpub-ncpu-ndb0 ~]# uptime21:06:13…

poj2420A Star not a Tree?(模拟退火)

链接 求某一点到其它点距离和最小&#xff0c;求这个和&#xff0c;这个点 为费马点。 做法&#xff1a;模拟退火 1 #include <iostream>2 #include<cstdio>3 #include<cstring>4 #include<algorithm>5 #include<stdlib.h>6 #include<vector&…

刀剑英雄登陆显示服务器繁忙,玩刀剑遇到问题解决方法

以下是目前在内测阶段玩家比较常见的一些问题&#xff0c;希望对大家有所帮助&#xff01;1.如果没有正确安装DX9.0B,可能会造成"执行文件BO.EXE时出错&#xff0c;错误代码:2"或者"错误代码:1157"等错误.一个验证方法就是直接运行Bo.exe文件如果提示"…

实战:一次失败的WEB攻击试验,欢迎高手补充

2019独角兽企业重金招聘Python工程师标准>>> 首先声明&#xff1a;这个文章我描述的是一次比较失败的WEB攻击试验&#xff0c;理论基础是一次在网上看到的一篇关于"慢攻击"的概念&#xff0c;那什么叫慢攻击呢&#xff1f; 在解释这个"慢攻击"概…

十大排序算法 导图总结

以下为我们经常用到的十大典型排序算法导图&#xff0c;很多设计以及优化的思想值得去参考学习 因为代码较多&#xff0c;所以都添加到对应的实现注释中了&#xff0c;相关代码可以从Mind-mapping获取xmind源文件 参考文档: 基数排序 堆排序 希尔排序 https://blog.csdn.net/r…

机器学习问题的十个实例【转】

机器学习是什么&#xff1f;这个问题的答案可以参考权威的机器学习定义&#xff0c;但是实际上&#xff0c;机器学习是由它所解决的问题定义的。因此&#xff0c;理解机器学习最好的方式是观察一些实例。 首先来看一些现实生活中众所周知和理解的机器学习问题的实例&#xff0c…

node项目部署到服务器报错,记一次部署node项目到centos服务器经历

&#xff1a;-}先从网上随便搜了个 contos 安装 node 的教程&#xff0c;大概就是这样。准备命令&#xff1a;yum -y install gcc make gcc-c openssl-devel wget下载源码及解压&#xff1a;编译及安装&#xff1a;cd node-v0.10.26make && make install验证是否安装配…