代理对象中使用this
- 开源代码
- 2025-09-19 04:24:02

一、问题引出
业务逻辑层代码
@Service public class DemoServiceImpl extends ServiceImpl<DemoMapper, Demo> implements DemoService, ApplicationContextAware { // 用于从Spring容器中获取指定Bean的对象 private ApplicationContext applicationContext; // 通过ApplicationContextAware接口完成applicationContext对象的注入 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void methodC() { System.out.println("使用this调用结果:"); this.methodD(); System.out.println("\n使用Bean对象调用结果:"); DemoServiceImpl bean = applicationContext.getBean(DemoServiceImpl.class); bean.methodD(); } public void methodD() { System.out.println("执行D方法……"); } }自定义切面:对DemoServiceImpl方法中的methodD方法进行增强,在前后打印相关内容
@Aspect @Component public class CustomAspect { @Around("execution(* com.example.service.*.methodD(..))") public void aspectMethod(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("aspectMethod before执行……"); joinPoint.proceed(); System.out.println("aspectMethod after执行……"); } }测试类
@SpringBootTest class DemoApplicationTests { @Test void contextLoads() { } @Resource private DemoService demoService; @Test void test() throws Exception { demoService.methodC(); } }测试结果:
使用this调用结果: 执行D方法…… 使用Bean对象调用结果: aspectMethod before执行…… 执行D方法…… aspectMethod after执行……**疑问:**之前学习的时候不是说this不是哪个对象调用就是哪个对象的引用类型(之间的理解有问题,应该是this始终指向当前对象的实例。在实例方法中,this 指向当前对象的实例;在构造方法中,this 指向正在被构造的对象),现在是通过demoService的代理对象(通过AOP进行增强,Spring在创建Bean对象的时候,会对该对象进行代理增强,并放入到IOC容器中)对methodC方法的调用,然后methodC中又通过this去调用methodD方法,那这个this不就是demoService的代理对象吗?methodD不就应该是代理对象的methodD,即增强后的methodD方法吗,但是实际上确实增强前的MethodD方法。
二、原因分析首先this是Java语言的一个关键字,指向当前对象的实例:
注意:如果通过代理对象调用方法,this 仍然指向 原始对象,而不是代理对象,因为 this 是 Java 语言的关键字,它的行为是由 Java 语言规范定义的,无法被 Spring 或其他框架修改。
this 的行为在编译期就已经确定,编译器会将 this 替换为当前对象的引用:
public class A { public void method() { System.out.println("Method called"); } public static void main(String[] args) { A a = new A(); a.method(); } }其在编译后等价于:
public class A { public void method(A this) { System.out.println("Method called"); } public static void main(String[] args) { A a = new A(); a.method(a); } }在实例方法调用时,编译器会隐式地将当前对象的引用作为第一个参数传递给方法,通过查看A对应的字节码可以看到,methodC方法的局部变量表中的第一个参数就是this,因此,this关键字实际上就是一个指向当前对象的隐式参数。
因此在上面的DemoServiceImpl的methodC方法中通过this调用methodD方法的时候,其实就是调用DemoServiceImpl实例对象的methodD方法,而不是Spring AOP代理对象的methodD方法,this 是在编译期确定的,指向 DemoServiceImpl 的实例。而通过Spring AOP创建的代理对象是在 运行时 动态生成的,this 仍然指向原始对象。
我们打一个断点,也可以看到this和bean这两个对象是不一样的,this就是DemoServiceImpl实例对象,而bean是通过Spring AOP增强后的代理对象(使用GCLIB进行代理)
总结:
this 是在编译期确定的:它指向当前对象的实例,无法被运行时修改。代理对象是运行时生成的:Spring 的代理对象无法改变 this 的行为。 尾言 参考文章 blog.csdn.net/benxiangsj/article/details/124282800 blog.csdn.net/weixin_53840353/article/det代理对象中使用this由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“代理对象中使用this”
上一篇
fps项目总结:关于攻击与受击