为什么feign动态代理不需要接口实现类?

feign动态代理是基于jdk动态代理来实现的:
所以按照模型 应该有feignClien接口类 + feignClient接口业务实现类 + InvocationHandler实现类, 我猜想 feign源码里会有InvocationHandler实现类, 但是feignClient接口业务实现类应该不是源码中某个类,而编写代码时也不需要提供这个实现类, 那feign究竟是怎么做到的呢?
image.png
按照上图,源码中Proxy.newInstance()返回的应该是业务接口实现类2的代理类4,常规的feign调用,是只需要开发提供业务接口1,那2是何时生成的?或者说为什么可以不提供2

阅读 4.3k
2 个回答

你猜想的很对,feign既然是jdk代理,最终执行的就是InvocationHandler,首先要知道一点,像mybatis,feign,jpa这种,直接注入接口的,交给容器管理以后,都是FactoryBean去生成运行时bean,feign的话,则是FeignClientFactoryBean,看一下它的getObject方法image.png
image.png
image.png
image.png
image.png
image.png
image.png

--
image.png
public void saveClassFile(Class clazz,String proxyName) {

    //生成class的字节数组,此处生成的class与proxy.newProxyInstance中生成的class除了代理类的名字不同,其它内容完全一致
    byte[] classFile = ProxyGenerator.generateProxyClass(proxyName, new Class[]{clazz});
    String path = clazz.getResource(".").getPath();
    try( FileOutputStream fos = new FileOutputStream(path + proxyName + ".class")) {

        fos.write(classFile);//保存到磁盘
        fos.flush();
    }catch(Exception e) {
        e.printStackTrace();
    }
}

image.png
image.png
image.png

按照一楼大佬的说法,在源码的这一步找到了feign生成的业务接口实现类,发现他的名称也是类似于Proxy0
image.png
另外通过以下方式没有拿到字节码,明天再做进一步的验证:
Object obj= getTarget();
byte[] bytes = null;
try {

// object to bytearray  
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(obj);

bytes = bo.toByteArray();

bo.close();
oo.close();

} catch (Exception e) {

System.out.println("translation" + e.getMessage());
e.printStackTrace();

}

FileOutputStream fos = new FileOutputStream(new File("Test.class"));
fos.write(bytes);
fos.flush();
fos.close();

4.5:尝试了一些方式都无法在debug时,将getTarget返回的对象转字节码, 还是无法完成最终的验证。 这个问题演变成了源码中返回的对象究竟是业务接口实现类 还是业务接口代理实现类?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题