V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liumyao
V2EX  ›  Java

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

  •  1
     
  •   liumyao ·
    MrLawrenc · 2019-07-25 18:05:31 +08:00 · 2694 次点击
    这是一个创建于 1977 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    (要是哪里写错了,谁提醒我一下
    ninjachen
        2
    ninjachen  
       2019-07-25 21:47:28 +08:00
    还有感觉你看得资料比较老,这些词貌似是好多年前看到的。。。
    liumyao
        3
    liumyao  
    OP
       2019-07-26 13:40:06 +08:00
    @ninjachen 我不明白的是比如我对 A 类需要增强,那么我在 B 类里面注入了 A 类对象 a ( autowired 注入),我通过 a 去调 A 类方法,这时候为什么会有增强的效果,难道是注入的 bean 不是 A 类对象,而是 A 的代理类对象吗?
    734695609
        4
    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
        5
    liumyao  
    OP
       2020-04-07 19:01:57 +08:00 via Android
    是的 哈哈 那是初学的疑惑 现在都忘了 后面看过 spring ioc 有代理的时候注入的代理对象 如果你想确定 可以 debug 走一下流程(注意打条件断点)。再说下事务失效的问题 项目中很常见 调用同类方法并不是用的代理对象 而是使用的原对象调用 在生成的代理类中保存有原对象(可以将生成的代理类保存到磁盘,使用 idea 反编译查看) 。具体解决就是你所说的用 currentProxy 方法获取代理对象或者利用 spring 事务传递特性
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2439 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 00:26 · PVG 08:26 · LAX 16:26 · JFK 19:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.