https://www.jianshu.com/p/096dbda7d528

代理方式

  1. public class RpcFactory implements InvocationHandler {
  2. @Autowired
  3. private NettyClient client;
  4. Logger logger = LoggerFactory.getLogger(this.getClass());
  5. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  6. Request request = new Request();
  7. request.setClassName(method.getDeclaringClass().getName());
  8. request.setMethodName(method.getName());
  9. request.setParameters(args);
  10. request.setParameterTypes(method.getParameterTypes());
  11. request.setId(IdUtil.getId());
  12. Object result = client.send(request);
  13. Class<?> returnType = method.getReturnType();
  14. Response response = JSON.parseObject(result.toString(), Response.class);
  15. if (response.getCode()==1){
  16. throw new Exception(response.getError_msg());
  17. }
  18. if (returnType.isPrimitive() || String.class.isAssignableFrom(returnType)){
  19. return response.getData();
  20. }else if (Collection.class.isAssignableFrom(returnType)){
  21. return JSONArray.parseArray(response.getData().toString(),Object.class);
  22. }else if(Map.class.isAssignableFrom(returnType)){
  23. return JSON.parseObject(response.getData().toString(),Map.class);
  24. }else{
  25. Object data = response.getData();
  26. return JSONObject.parseObject(data.toString(), returnType);
  27. }
  28. }
  29. }
  1. package com.viewscenes.netsupervisor.configurer.rpc;
  2. import org.springframework.beans.factory.FactoryBean;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.beans.factory.support.AbstractBeanFactory;
  5. import org.springframework.context.support.AbstractApplicationContext;
  6. import java.lang.reflect.Proxy;
  7. /**
  8. * Created by MACHENIKE on 2018-12-03.
  9. */
  10. public class RpcFactoryBean<T> implements FactoryBean<T> {
  11. private Class<T> rpcInterface;
  12. @Autowired
  13. private RpcFactory<T> factory;
  14. /**
  15. * {@link AbstractApplicationContext#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)}
  16. * 会通过 rpcInterface 实例化 RpcFactoryBean
  17. * @param rpcInterface
  18. */
  19. public RpcFactoryBean(Class<T> rpcInterface) {
  20. this.rpcInterface = rpcInterface;
  21. }
  22. /**
  23. * 把 Bean 的定义 GenericBeanDefinition 放到了容器之后,就需要初始化这些 Bean,
  24. * 而 Bean 的初始化时机有2个:
  25. * 1、在程序第一个主动调用 getBean 的时候
  26. * 2、在完成容器初始化的时候会初始化 lazy-init 配置为 false 的Bean(默认为false)
  27. * 在这里,由于 RpcFactoryBean 未设置懒加载,故初始化的时机是第二种。上面两种初始化的过程都是一样的,
  28. * 都会调用 {@link AbstractBeanFactory#doGetBean(java.lang.String, java.lang.Class, java.lang.Object[], boolean) 方法,
  29. * 里面有个方法 getObjectForBeanInstance,会判断当前的 Bean 是否实现了 {@link FactoryBean}。
  30. * 如果该 Bean 未实现 FactoryBean 接口,则直接返回该Bean实例;
  31. * 如果该 Bean 实现了 FactoryBean 接口,则会返回的实例是 getObject() 返回值。
  32. * @return
  33. * @throws Exception
  34. */
  35. public T getObject() throws Exception {
  36. return getRpc();
  37. }
  38. public Class<?> getObjectType() {
  39. return this.rpcInterface;
  40. }
  41. public boolean isSingleton() {
  42. return true;
  43. }
  44. /**
  45. * JDK 动态代理,当调用 rpcInterface 接口的方法时,会走 factory 的 invoke 方法
  46. * @param <T>
  47. * @return
  48. */
  49. public <T> T getRpc() {
  50. return (T) Proxy.newProxyInstance(rpcInterface.getClassLoader(), new Class[] { rpcInterface },factory);
  51. }
  52. }
  1. // 0.容器启动
  2. 1.编码是要实现FactoryBean类,getObjectType方法通过外部传入用于初始化,getObject方法返回代理对象。
  3. 1.编码时需要标记哪些服务是rpc beandubbo:reference, sofa:reference ...)。
  4. 2.spring容器启动时基于bean加载注册时某些扩展点的进行判断为rpc bean
  5. 针对rpc bean进行改造,将其BeanDefiniationClass改为自定义的FactoryBean
  6. 并改为按type注册,也就是FactoryBean.getObjectType方法。
  7. 3.BeanDefiniation实例化时(注册或者首次使用)会判断是否是FactoryBean实现类,
  8. 如果是会通过FactoryBean.getObject方法来返回实例对象(代理对象)。
  9. 4.代理对象在执行时实际执行时通过socket通信获取结果。并不会实际调用method.invoke,或者说
  10. 这一步被推到服务端进行执行了。
  11. // 1.Client
  12. class XXClientImpl{
  13. @AutoWired
  14. private UserService userService;
  15. public void doSomething(){
  16. userService.getUser();
  17. }
  18. }
  19. // 2. 客户端通过动态代理 + socket(netty) + 服务端通过反射
  20. // FactoryBean是springIoC提供的一项比较方便来实现动态代理类注册的功能,因为它把实现对象和注册类
  21. // 在分化开来,并在框架内给予了特殊处理。
  22. // 想想一下,如果没有FactoryBean,如何处理?也就是要把代理类作为普通bean来注册,这就需要一个地方来
  23. // 维护jar类和代理类之间的关系,或者基于约定大于配置的思想,通过名称来关联。