zoukankan      html  css  js  c++  java
  • 静态代理和动态代理

     

     

    静态代理

    • 抽象角色:定义行为
    • 真实角色:行为的具体实现
    • 代理角色:代理真实角色,增强真实角色
    • 使用者:和代理角色打交道

    抽象角色

    package com.mage.staticproxy;
    
    /**
     * 抽象角色:定义行为
     */
    public interface Rent {
    
        /**
         * 出租房屋
         */
        void rentHouse();
    
    }
    

    真实角色

    package com.mage.staticproxy;
    
    /**
     * 真实角色:行为的具体实现
     */
    public class Host implements Rent {
    
        @Override
        public void rentHouse() {
            System.out.println("两室一厅,月租五千。");
        }
    
    }
    

    代理角色

    package com.mage.staticproxy;
    
    /**
     * 代理角色:代理真实角色,增强真实角色
     */
    public class StaticAgent implements Rent {
    
        private Rent rent;
    
        @Override
        public void rentHouse() {
            System.out.println("带客户看房,打扫房间。");
            rent.rentHouse();
            System.out.println("谈价钱,签订合同。");
        }
    
        public StaticAgent(Rent rent) {
            this.rent = rent;
        }
    
        public void setRent(Rent rent) {
            this.rent = rent;
        }
    }
    

    调用

    package com.mage.staticproxy;
    
    /**
     * 客户:与代理打交道
     */
    public class Client {
    
        public static void main(String[] args) {
            Host host = new Host();// 一个房东
            StaticAgent agent = new StaticAgent(host);// 代理真实角色
            agent.rentHouse();
        }
    
    }
    

    总结

    使用简单,项目中如果只有个别业务需要代理类,可以使用静态代理。

    动态代理

    • 实现 InvocationHandler
    • 通过 Proxy.newProxyInstance(通过环境内的对象拿到类加载器, 代理需要实现的接口, 一个InvocationHandler的实例)
    package com.mage.dynamicproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class DynamicAgent implements InvocationHandler {
    
        private Object target;// 目标对象
    
        /**
         * 获取代理对象
         *
         * @return
         */
        public Object getProxy(Object target) {
            this.target = target;
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(method.getName() + " -- 方法执行前做一些处理。");
            Object result = method.invoke(target, args);
            for (Object arg : args) {
                System.out.println("arg = " + arg);
            }
            System.out.println("result = " + result);
            System.out.println(method.getName() + " -- " + "方法执行后做一些处理。");
            return result;
        }
    
    }
    

    调用

    package com.mage.dynamicproxy;
    
    /**
     * 客户:与代理打交道
     */
    public class Client {
    
        public static void main(String[] args) {
            Host host = new Host();// 一个房东
            DynamicAgent agent = new DynamicAgent();
            Rent rent = (Rent) agent.getProxy(host);
            rent.rentHouse(5000.00D);
        }
    
    }
    

    总结

    灵活,通过反射的机制根据传入的对象获取对应的接口,创建该接口的实现类(代理类)返回给调用者。

  • 相关阅读:
    自定义ASP.NET MVC Html标签辅助方法
    解决github.com无法访问
    Func<>用法
    Entity Framework 在OrderBy排序中使用字符串
    <input type="file"> 标签详解
    JS实现上传图片的三种方法并实现预览图片功能
    一个关于双目运算符的测试
    堆和栈的区别
    C# 代码笔记_tuple元组
    小程序前后端自定义登录与一键登录兼容demo分享
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/14576218.html
Copyright © 2011-2022 走看看