自定义注解实现RPC远程调用

2021-02-24  本文已影响0人  秋风落叶黄

源码地址:https://github.com/huangyichun/remotetransfer

本文涉及知识点:

项目背景:由于原直播系统采用SpringCloud部署在虚拟机(仅使用SpringCloud的注册中心),现打算使用k8s部署,由于k8s和SpringCloud功能很多重合了,如果在k8s系统使用SpringCloud将无法用到k8s的注册中心、负载均衡等功能,而且项目部署也过臃肿。 因此有2种方案:

具体实现:

创建 RemoteTransferRegister类,并实现BeanFactoryPostProcessor接口,该接口的方法postProcessBeanFactory是在bean被实例化之前被调用的。这样保证了自定义注解声明的Bean能被其他模块Bean依赖。

/**
 * @Author: huangyichun
 * @Date: 2021/2/23
 */
@Slf4j
@Component
public class RemoteTransferRegister implements BeanFactoryPostProcessor {

    /**
     * 设置扫描的包
     */
    private static final String SCAN_PATH = "com.huang.web";

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        RemoteTransferInvoke transferInvoke = new RemoteTransferInvoke(invokeRestTemplate());

        //扫描注解声明类
        Set<Class<?>> classSet = new Reflections(SCAN_PATH).getTypesAnnotatedWith(RemoteTransfer.class);
        for (Class<?> cls : classSet) {
            log.info("create proxy class name:{}", cls.getName());

            //动态代理的handler
            InvocationHandler handler = (proxy, method, args) -> transferInvoke.invoke(cls, method, args);
            //生成代理类
            Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class<?>[]{cls}, handler);

            //注册到Spring容器
            beanFactory.registerSingleton(cls.getName(), proxy);
        }
    }
  
  private RestTemplate invokeRestTemplate() {
       //生成restTemplate 省略代码 
  }
}

注解的具体使用:

@RemoteTransfer(hostName = "TRADE-PLAY")
public interface TradePlayServiceApi {

     @GetMapping("/open/get")
     String test(@RequestParam("type") String type);

     @PostMapping("/open/post")
     ResponseResult post(@RequestBody PostRequest request);
}

测试类:

@SpringBootTest
class WebApplicationTests {

    @Autowired
    private TradePlayServiceApi tradePlayServiceApi;

    @Test
    public void get() {
        String type = tradePlayServiceApi.test("type");
        System.out.println(type);
    }

    @Test
    public void post() {
        PostRequest request = new PostRequest();
        request.setId("id");
        PostRequest.Person person = new PostRequest.Person("name", "age");

        request.setPerson(person);
        ResponseResult post = tradePlayServiceApi.post(request);
        System.out.println(post);
    }
}

最终测试通过,请求正常返回。

上一篇下一篇

猜你喜欢

热点阅读