【RPC通信框架】基于接口的客户端实现动态代理原理
一、接口的代理类实现
1、客户端接口代理类
package com.spring.sxf.study.springtradedao.reflector.demo; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; /** * * @date 7:44 PM 2019/12/26 */ public class PayFactory implements FactoryBean<Object>, InitializingBean { /** * 要代理的远程接口 */ private Class<?> face; /** * 对接口生成的代理对象 */ private Object proxy; public void setFace(Class<?> cls) { this.face = cls; } @Override public Object getObject() throws Exception { return proxy; } @Override public Class<?> getObjectType() { return face; } @Override public void afterPropertiesSet() throws Exception { //基于spring的aop代理机制,生成代理对象 proxy = new ProxyFactory(face, new RemoteHandler()).getProxy(); } } /** * 处理客户端请求的实现 */ class RemoteHandler implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { //可以在该方法内实现服务发现,服务路由 String name = invocation.getMethod().getName(); Object[] arg=invocation.getArguments(); System.out.println("methodName=>" + name); if("pay".equals(name)){ Req req= (Req) arg[0]; System.out.println("请求信息如下:["+req.getName()+"]["+req.getAge()+"]"); PayRes payRes=new PayRes(); payRes.setMsg("success"); payRes.setTag(true); return payRes; }else{ return "我是中国人"; } } }
2、远程接口信息
package com.spring.sxf.study.springtradedao.reflector.demo; /** * * @date 7:40 PM 2019/12/26 */ public interface PayService { PayRes pay(Req req); String refund(String refundNo); } package com.spring.sxf.study.springtradedao.reflector.demo; /** * @date 7:41 PM 2019/12/26 */ public class Req { private String name; private long age; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getAge() { return age; } public void setAge(long age) { this.age = age; } } package com.spring.sxf.study.springtradedao.reflector.demo; /** * @date 7:41 PM 2019/12/26 */ public class PayRes { private boolean tag; private String msg; public boolean isTag() { return tag; } public void setTag(boolean tag) { this.tag = tag; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
3、测试
package com.spring.sxf.study.springtradedao.reflector.Test; import com.spring.sxf.study.springtradedao.reflector.demo.PayFactory; import com.spring.sxf.study.springtradedao.reflector.demo.PayRes; import com.spring.sxf.study.springtradedao.reflector.demo.PayService; import com.spring.sxf.study.springtradedao.reflector.demo.Req; import org.springframework.aop.support.AopUtils; import org.springframework.core.io.DefaultResourceLoader; import java.lang.reflect.Method; /** * @date 8:09 PM 2019/12/26 */ public class Test { public static void main(String[] args) throws Exception { testProxy(); // testReflector(); } /** * methodName=>pay * 请求信息如下:[sxf][100] * 响应结果为:success * methodName=>refund * result=>我是中国人 * @throws Exception */ public static void testProxy() throws Exception { PayFactory payFactory=new PayFactory(); payFactory.setFace(PayService.class); payFactory.afterPropertiesSet(); PayService payService= (PayService) payFactory.getObject(); Req req=new Req(); req.setName("sxf"); req.setAge(100); PayRes payRes=payService.pay(req); System.out.println("响应结果为:"+payRes.getMsg()); String result=payService.refund("122333"); System.out.println("result=>"+result); } /** * 当前对象为代理对象 * 当前代理对象的代理的类为=>class com.sun.proxy.$Proxy0 * 目标代理类为=>interface com.spring.sxf.study.springtradedao.reflector.demo.PayService * @throws Exception */ public static void testReflector() throws Exception { PayFactory payFactory=new PayFactory(); payFactory.setFace(PayService.class); payFactory.afterPropertiesSet(); PayService payService= (PayService) payFactory.getObject(); if(AopUtils.isAopProxy(payService)){ System.out.println("当前对象为代理对象"); Class<?> cls=AopUtils.getTargetClass(payService); System.out.println("当前代理对象的代理的类为=>"+cls); Class target=payFactory.getObjectType(); System.out.println("目标代理类为=>"+target); Method method=null; Method[] methods= target.getDeclaredMethods(); for(Method method1:methods){ if(method1.getName().equals("pay")){ method=method1; } } Req req=new Req(); req.setName("sxf"); req.setAge(100); PayRes o = (PayRes) method.invoke(payService,req); System.out.println("执行结果=>"+o.getMsg()); }else{ System.out.println("class=>"+payService.getClass()); } } }