动态代理的简单实用

这两天在研读大众点评所采用的分布式任务调度系统,发现了许雪里的许多值得我学习的代码。其中让我印象最深的就是调度中心向执行器分发任务的代码,在执行器和调度中心之间的通信使用的是内置的jetty服务器(总感觉netty更好一点,毕竟是传输层)。

调度中心使用动态代理,在执行某服务的方法的过程中,通过反射的方式获得要执行的方法名, 方法参数然后将其 封装为一个request 传递给执行器,执行器再对调度中心的request进行解析,通过反射来执行相应的任务。

在这里简单模拟了一下:

/**
 *
 * @author xiaosuda
 * @date 2018/2/6
 */
public class MastNode {

    public static void main(String [] args){
        MastNode mastNode = new MastNode();
        ProxyFactory proxyFactory = mastNode.new ProxyFactory(new BirdServiceImpl(), BirdService.class);
        BirdService proxy = (BirdService) proxyFactory.getProxy();
        System.out.println(proxy.say("叽叽喳喳", 6));
        System.out.println(proxy.walk(5));

    }

    class ProxyFactory {
        private Object obj;
        private Class< ? extends Object> cla;

        public ProxyFactory(Object obj, Class< ? extends Object> cla){
            this.obj = obj;
            this.cla = cla;
        }

        public Object getProxy() {
            return Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { cla }, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    RpcRequest rpcRequest = new RpcRequest();
                    rpcRequest.setServiceBean(obj);
                    rpcRequest.setMethodName(method.getName());
                    rpcRequest.setParameterTypes(method.getParameterTypes());
                    rpcRequest.setParameters(args);

                    WorkNode workNode = new WorkNode();
                    return workNode.executeRpcMethod(rpcRequest);
                }
            });
        }
    }
}


class WorkNode {
    public Object executeRpcMethod(RpcRequest request) throws InvocationTargetException {
        String methodName = request.getMethodName();
        Class<?>[] parameterTypes = request.getParameterTypes();
        Object[] parameters = request.getParameters();
        Object serviceBean = request.getServiceBean();
        FastClass serviceFastClass = FastClass.create(serviceBean.getClass());
        FastMethod serviceFastClassMethod = serviceFastClass.getMethod(methodName, parameterTypes);
        Object result = serviceFastClassMethod.invoke(serviceBean, parameters);
        return "远程执行结果:{" + result + "}";

    }
}

class RpcRequest {
    private Object serviceBean;
    private String methodName;
    private Class<?>[] parameterTypes;
    private Object[] parameters;

    public void setServiceBean(Object serviceBean) {
        this.serviceBean = serviceBean;
    }

    public Object getServiceBean() {
        return serviceBean;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public Class<?>[] getParameterTypes() {
        return parameterTypes;
    }

    public void setParameterTypes(Class<?>[] parameterTypes) {
        this.parameterTypes = parameterTypes;
    }

    public Object[] getParameters() {
        return parameters;
    }

    public void setParameters(Object[] parameters) {
        this.parameters = parameters;
    }
}

class BirdServiceImpl implements BirdService{
    @Override
    public String say(String content, Integer times) {

        for (int i = 0; i < times; i++) {
            System.out.println(content + " ");
        }

        StringBuilder sb = new StringBuilder();
        sb.append("该小鸟鸣叫内容:").append(content).append(",鸣叫次数:").append(times);
        return sb.toString();
    }

    @Override
    public String walk(Integer steps) {
        for (int i = 0; i < steps; i++) {
            System.out.println("行走一步");
        }

        StringBuilder sb = new StringBuilder();
        sb.append("该小鸟行走了").append(steps).append("步");
        return sb.toString();
    }
}

interface BirdService {
    /**
     *
     * @param content
     * @param times
     * @return
     */
    String say(String content, Integer times);

    /**
     *
     * @param steps
     * @return
     */
    String walk(Integer steps);

执行结果:

叽叽喳喳 
叽叽喳喳 
叽叽喳喳 
叽叽喳喳 
叽叽喳喳 
叽叽喳喳 
远程执行结果:{该小鸟鸣叫内容:叽叽喳喳,鸣叫次数:6}
行走一步
行走一步
行走一步
行走一步
行走一步
远程执行结果:{该小鸟行走了5步}
展开阅读全文
©️2020 CSDN 皮肤主题: 像素格子 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值