Spring this调用当前类方法无法拦截的示例代码


Posted in Java/Android onMarch 20, 2022

先给出代码示例

package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
public class ProxyService {
    public void  testA(){
        System.out.println("进入A");
        this.testB();
    }
    public void testB() {
        System.out.println("进入b");
    }

}
package com.example.demo.annotation;
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 AspectjTest {
    @Around("execution(* com.example.demo.service.ProxyService.testB())")
    public void recordProxy(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        joinPoint.proceed();
        long end = System.currentTimeMillis();
        System.out.println("花费时间:"+(end-start));
    }
}
package com.example.demo.api;
import com.example.demo.service.ProxyService;
import com.example.demo.service.UserService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ProxyApi {
//    @Autowired
//    ProxyService proxyService1;
    @Autowired
    private ApplicationContext applicationContext;
    @PostMapping("/proxy")
    public String test1() {
        ProxyService proxyService1 =  applicationContext.getBean(ProxyService.class);;
        proxyService1.testA();
        return "string";
    }
}

运行上面的代码会发现 配置aop 拦截方法不会被执行

Spring this调用当前类方法无法拦截的示例代码

我们通过debug 查看这个proxyService1 和this的区别,看看他们的值是什么

Spring this调用当前类方法无法拦截的示例代码

Spring this调用当前类方法无法拦截的示例代码

发现不一样,其实这就是问题的原因。

1、当我们在aop配置拦截的时候会指定类下面的方法路径,在spring启动的时候会先去加载这个ProxyService类,生成一个bean,但是因为你用aop配置了,所以需要代理这个ProxyService类,所以最终存在spring容器中的bean对象就是被代理后的bean对象。所以,我们在用容器获取bean或者用依赖注入获取bean的地址路径显示的是被代理后的bean 。
2、this获取的当前对象方法的一个引用,所以在调用testB方法的时候用的不是被代理的对象,自热不会经过aop拦截,原理和我们使用普通动态代理一样,只能是代理对象才能走自定义的方法。
3、可以通过debug 查看当ProxyService类被代理前和后的zhi值

Spring this调用当前类方法无法拦截的示例代码

Spring this调用当前类方法无法拦截的示例代码

发现是和之前的debug截图里面的值相符合的哈。

解决方法,就是在调用testB方法的时候用spring容器里的bean对象

@Service
public class ProxyService {
    @Autowired
    private  ProxyService proxyService;
    
    public void  testA(){
        System.out.println("进入A");
        proxyService.testB();
    }
    public void testB() {
        System.out.println("进入b");
}

或者

@Service
public class ProxyService {
    public void  testA(){
        System.out.println("进入A");
        ProxyService currentProxy = (ProxyService) AopContext.currentProxy();
        currentProxy.testB();
    }
    public void testB() {
        System.out.println("进入b");
    }
}

最终结果正确

Spring this调用当前类方法无法拦截的示例代码

到此这篇关于Spring this调用当前类方法无法拦截的文章就介绍到这了,更多相关Spring this无法拦截内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Java/Android 相关文章推荐
Java内存模型之happens-before概念详解
Jun 13 Java/Android
Spring Data JPA的Audit功能审计数据库的变更
Jun 26 Java/Android
详细了解MVC+proxy
Jul 09 Java/Android
Java日常练习题,每天进步一点点(38)
Jul 26 Java/Android
浅谈Java父子类加载顺序
Aug 04 Java/Android
SpringBoot2零基础到精通之异常处理与web原生组件注入
Mar 22 Java/Android
Android开发实现极为简单的QQ登录页面
Apr 24 Java/Android
JAVA 线程池(池化技术)的实现原理
Apr 28 Java/Android
Springboot中如何自动转JSON输出
Jun 16 Java/Android
Spring Cloud OpenFeign模版化客户端
Jun 25 Java/Android
Java 多线程并发FutureTask
Jun 28 Java/Android
SpringBoot项目部署到阿里云服务器的实现步骤
Jun 28 Java/Android
SpringCloud Feign请求头删除修改的操作代码
Mar 20 #Java/Android
JavaWeb实现显示mysql数据库数据
关于Mybatis中SQL节点的深入解析
springboot 自定义配置 解决Boolean属性不生效
Mar 18 #Java/Android
使用Java去实现超市会员管理系统
Mar 18 #Java/Android
详解Spring Security中的HttpBasic登录验证模式
RestTemplate如何通过HTTP Basic Auth认证示例说明
You might like
phpMyAdmin下载、安装和使用入门教程
2007/05/31 PHP
PHP+Ajax异步通讯实现用户名邮箱验证是否已注册( 2种方法实现)
2011/12/28 PHP
php配置php-fpm启动参数及配置详解
2013/11/04 PHP
解决phpcms更换javascript的幻灯片代码调用图片问题
2014/12/26 PHP
PHPCMS忘记后台密码的解决办法
2016/10/30 PHP
php实现替换手机号中间数字为*号及隐藏IP最后几位的方法
2016/11/16 PHP
laravel5.4生成验证码的实例讲解
2017/08/05 PHP
无阻塞加载脚本分析[全]
2011/01/20 Javascript
js获取select标签选中值的两种方式
2014/01/09 Javascript
通过正则表达式获取url中参数的简单实现
2016/06/07 Javascript
Vue.js学习笔记之 helloworld
2016/08/14 Javascript
通过AngularJS实现图片上传及缩略图展示示例
2017/01/03 Javascript
JS实现点击表头表格自动排序(含数字、字符串、日期)
2017/01/22 Javascript
JavaScript 过滤关键字
2017/03/20 Javascript
nvm、nrm、npm 安装和使用详解(小结)
2019/01/17 Javascript
详解原生JS动态添加和删除类
2019/03/26 Javascript
原生js实现3D轮播图
2020/03/21 Javascript
JavaScript的变量声明与声明提前用法实例分析
2019/11/26 Javascript
TypeScript之调用栈的实现
2019/12/31 Javascript
Vue实现腾讯云点播视频上传功能的实现代码
2020/08/17 Javascript
python实现图片变亮或者变暗的方法
2015/06/01 Python
python类:class创建、数据方法属性及访问控制详解
2016/07/25 Python
用tensorflow实现弹性网络回归算法
2018/01/09 Python
matplotlib作图添加表格实例代码
2018/01/23 Python
pytest中文文档之编写断言
2019/09/12 Python
python实现人性化显示金额数字实例详解
2020/09/25 Python
CSS3实现跳动的动画效果
2016/09/12 HTML / CSS
CSS3中31种选择器使用方法教程
2013/12/05 HTML / CSS
大学生学习2014全国两会心得体会
2014/03/13 职场文书
学习张丽丽心得体会
2014/09/03 职场文书
员工离职通知函
2015/04/25 职场文书
交通安全教育主题班会
2015/08/12 职场文书
小学数学教师研修日志
2015/11/13 职场文书
2019年大学推荐信
2019/06/24 职场文书
python超详细实现完整学生成绩管理系统
2022/03/17 Python
nginx容器方式反向代理实战
2022/04/18 Servers