关于 jdk 动态代理的一点疑问 希望大佬们能解答一下 万分感谢

2019-07-25 18:05:31 +08:00
 liumyao

1.在 spring 中,如果被代理的类没有交给 spring 是不是不能实现动态代理 2.我想知道的是,我有一个类加了 aop 注解,切面是 controller,http 在请求 controller 的时候是不是没有调用 controller 的方法,实际上是调用的 contoller 的代理对象的方法? 3.我知道 jdk 的动态代理,也能写出来,在生成代理对象的时候是根据接口强转了代理对象的,但就是不明白在 spring 中为什么可以增强,他是怎么将生成的代理对象向上转型的(向接口);

本人刚工作 也刚来社区 希望各位大佬解惑 谢谢啦

2662 次点击
所在节点    Java
5 条回复
ninjachen
2019-07-25 21:46:26 +08:00
1 可以自己实现动态代理
2 你都面向切面了,当然是动态代理啊
3 没听懂。所有实现类的都可以向上转型后操作。
例如
InterfaceImpl impl;
Interface i = impl;
i.api();

(要是哪里写错了,谁提醒我一下
ninjachen
2019-07-25 21:47:28 +08:00
还有感觉你看得资料比较老,这些词貌似是好多年前看到的。。。
liumyao
2019-07-26 13:40:06 +08:00
@ninjachen 我不明白的是比如我对 A 类需要增强,那么我在 B 类里面注入了 A 类对象 a ( autowired 注入),我通过 a 去调 A 类方法,这时候为什么会有增强的效果,难道是注入的 bean 不是 A 类对象,而是 A 的代理类对象吗?
734695609
2020-04-07 16:48:41 +08:00
@liumyao
我的结论:注入的是代理对象。如果有错误,麻烦和我说一下,感谢

楼主,我在 springboot 中测试了一下,用的是 cglib,controller 调 service,使用 AopContext.currentProxy()打断点,发现当前代理类是 controller 的 cglib 代理类。
然后关键是我的 servic 中的方法 A 调用 同一 service 中的方法 B,
service{

public A(){
this.B();
}

@Transactional
public B(){
}
此时方法 B 的注解失效

然后我看了一篇文章,链接为 https://my.oschina.net/guangshan/blog/1807721
说 this 调用的不是代理类中的方法,可以使用 applicationContext.getBean(service.class),在用这个 bean 调用方法 B 可以解决,所以可以判断注入的是代理对象,但是 this 调用原来的本类实例的方法
但是我的问题是 ioc 容器中存放的是代理类实例还是原本的类的实例 ?
我上面文章的链接是说代理类中有原本类实例,导致 this 调用了原来的没有增强过的方法
liumyao
2020-04-07 19:01:57 +08:00
是的 哈哈 那是初学的疑惑 现在都忘了 后面看过 spring ioc 有代理的时候注入的代理对象 如果你想确定 可以 debug 走一下流程(注意打条件断点)。再说下事务失效的问题 项目中很常见 调用同类方法并不是用的代理对象 而是使用的原对象调用 在生成的代理类中保存有原对象(可以将生成的代理类保存到磁盘,使用 idea 反编译查看) 。具体解决就是你所说的用 currentProxy 方法获取代理对象或者利用 spring 事务传递特性

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/586213

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX