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

先给出代码示例

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 拦截方法不会被执行

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

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

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

发现是和之前的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无法拦截内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring事务失效的一种原因关于this调用的问题

    PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务.如果没有事务则开启事务: PROPAGATION_REQUIRES_NEW:总是开启一个新的事务.如果一个事务已经存在,则将这个存在的事务挂起: 问题: Spring中一个没有事务的方法A调用一个默认事务(PROPAGATION_REQUIRED)的方法B时,如果使用this调用方法B,方法B抛出RuntimeException,此时方法B事务未生效,不会回滚. @Service public class Employ

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

    先给出代码示例 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"

  • Spring Security OAuth2 实现登录互踢的示例代码

    本文主要介绍了Spring Security OAuth2 实现登录互踢的示例代码,分享给大家,具体如下: 背景说明 一个账号只能一处登录,类似的业务需求在现有后管类系统是非常常见的. 但在原有的 spring security oauth2 令牌方法流程(所谓的登录)无法满足类似的需求. 我们先来看 TokenEndpoint 的方法流程 客户端 带参访问 /oauth/token 接口,最后去调用 TokenGranter TokenGranter 根据不同的授权类型,获取用户认证信息 并去

  • Java调用微信支付功能的方法示例代码

    Java 使用微信支付 前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用. 因为涉及二维码的前端显示,所以有前端的内容 一. 准备工作 所需微信公众号信息配置 APPID:绑定支付的APPID(必须配置) MCHID:商户号(必须配置) KEY:商户支付密钥,参考开户邮件设置(必须配置) APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置) 我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供 二

  • Spring Cloud 系列之负载均衡 Ribbon的示例代码

    1.1 简介 1.1.1 概述   Ribbon 是 Netflix 发布的负载均衡器,它有助于控制 HTTP 和 TCP 客户端的行为.为 Ribbon 配置服务提供者地址列表后,Ribbon 就可基于某种负载均衡算法,自动地帮助服务消费者去请求.Ribbon 默认为我们提供了很多的负载均衡算法,例如轮询.随机等.当然,我们也可为 Ribbon 实现自定义的负载均衡算法.Ribbon 现在已经进入维护状态,但目前仍在大规模使用,Spring Cloud 准备使用 LoadBalancer 作为

  • spring中使用mybatis实现批量插入的示例代码

    有3种实现方式:foreach,spring事务,以及ExecutorType.BATCH. 1. foreach方式 这种方式实际是对SQL语句进行拼接,生成一个长长的SQL,对很多变量进行绑定.如果数据量不大(1000个以内),可以用这种方式.如果数据量太大,可能数据库会报错. 定义接口 public interface StudentMapper05 { public void insertStudent(List<Student> studentList); } 定义mapper 适用

  • C#调用摄像头实现拍照功能的示例代码

    前言 老师要求我们学生做一套拍照身份验证系统,经过长时间的学习,有了这篇文章,希望能帮到读者们. 正文 首先介绍本文的主角:AForge 创建一个C#项目,引用必备的几个DLL AForge.dll AForge.Controls.dll AForge.Imaging.dll AForge.Math.dll AForge.Video.DirectShow.dll AForge.Video.dll 这些DLL读者们可以在文末下载我附带的Demon 引用必要的命名空间 using AForge.Co

  • spring cloud oauth2 实现用户认证登录的示例代码

    需求 在微服务架构中,我们有很多业务模块,每个模块都需要有用户认证,权限校验.有时候也会接入来自第三方厂商的应用.要求是只登录一次,即可在各个服务的授权范围内进行操作.看到这个需求,立马就想到了这不就是单点登录吗?于是基于这样的需求,作者使用spring-cloud-oauth2去简单的实现了下用户认证和单点登录. 相关介绍 OAuth2 OAuth2是一个关于授权的网络标准,他定制了设计思路和执行流程.OAuth2一共有四种授权模式:授权码模式(authorization code).简化模式

  • C#调用HTTP POST请求上传图片的示例代码

    现在很多B/S系统的开发都是通过API方式来进行的,一般服务端会开放一个API接口,客户端调用API接口来实现图片或文件上传的功能. GET和POST是什么?HTTP协议中的两种发送请求的方法. HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议. HTTP的底层是TCP/IP.所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接.GET和POST能做的事情是一样一样的.你要给GET加上request body,给POST带上url参

  • SpringBoot拦截器实现登录拦截的示例代码

    可以对URL路径进行拦截,可以用于权限验证.解决乱码.操作日志记录.性能监控.异常处理等 实现代码 新建 interceptor包 添加拦截器代码 package com.qcby.interceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.method.HandlerMethod; import org.springframework.web

  • spring boot整合Shiro实现单点登录的示例代码

    Shiro是什么 Shiro是一个Java平台的开源权限框架,用于认证和访问授权.具体来说,满足对如下元素的支持: 用户,角色,权限(仅仅是操作权限,数据权限必须与业务需求紧密结合),资源(url). 用户分配角色,角色定义权限. 访问授权时支持角色或者权限,并且支持多级的权限定义. Q:对组的支持? A:shiro默认不支持对组设置权限. Q:是否可以满足对组进行角色分配的需求? A:扩展Realm,可以支持对组进行分配角色,其实就是给该组下的所有用户分配权限. Q:对数据权限的支持? 在业务

随机推荐