美文网首页
代理模式 ~ 设计模式之七

代理模式 ~ 设计模式之七

作者: 喏喏2021 | 来源:发表于2022-01-17 18:09 被阅读0次

    1. 什么是代理

    我们不直接访问目标对象,而是访问第三方对象,通过这个对象完成目标对象的功能,类似现实中的房屋中介的作用

    2. 为什么要用代理

    我们就拿房屋中介的例子来讲

    1. 保护了房东的隐私
      一般我们不需要直接和房东联系,对于房东来讲,最后成功交易的就只有一个,其他的,对他来说都是骚扰,呵呵。
    2. 交流便利性
      中介是专业做这个的,对房屋信息,周边环境,人员支持上都会方便一点,而且可能非常热情
    3. 额外服务
      比如一些和银行贷款,房产交易中心的一些信息同步、沟通等,相关手续的办理等,效率也非常地高

    3. 具体实现

    代理一般我们分为静态代理和动态代理
    静态代理:就是在程序运行之前,代理类.class文件就已经存在
    动态代理:就是使用反射机制,程序运行中动态生成的

    1. 静态代理实现
    public class StaticProxyTest {
        //售卖房屋抽象
        static interface House {
            void sale();
        }
        //被代理对象
        static class HouseOwner implements House {
            @Override
            public void sale() {
                // TODO Auto-generated method stub
                System.out.println("房东售房");
            }
        }
        //代理对象
        static class HouseAgent implements House {
            //存放代理对象
            private HouseOwner owner;
            public HouseAgent(HouseOwner owner) {
                this.owner = owner;
            }
            
            @Override
            public void sale() {
                System.out.println("中介代理售房开始");
                //中间使用代理对象的实际业务
                owner.sale();
                System.out.println("中介代理售房结束");
            }
        }
        public static void main(String[] args) {
            //生成中介代理,需要传进一个房东
            HouseAgent agent = new HouseAgent(new HouseOwner());
            //增强的售卖功能
            agent.sale();
        }
    }
    //中介代理售房开始
    //房东售房
    //中介代理售房结束
    
    

    静态代理总结:

    • 优点:符合开闭原则,在添加代理方法时,不需要修改原来的方法
    • 缺点:维护起来比较麻烦,每一个代理服务,可能需要单独创建一个类,然后如果原方法发生变化时,代码方法也需要相应的调整,这时我们的动态代理就派上用场了。
    1. 动态代理实现
      动态代理基本有两种:JDK自带的动态代理和Cglib动态代理。
      1)JDK自带的动态代理
    public class DynamicProxyTest1 {
        // 售卖房屋抽象
        static interface House {
            void sale();
        }
    
        // 被代理对象
        static class HouseOwner implements House {
            @Override
            public void sale() {
                // TODO Auto-generated method stub
                System.out.println("房东售房");
            }
        }
        // 动态代理
        static class HouseDynamicProxy implements InvocationHandler {
            private Object obj;
            
            public HouseDynamicProxy(final Object obj) {
                this.obj = obj;
            }
            
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("中介代理售房开始");
                Object result = method.invoke(obj, args);
                System.out.println("中介代理售房结束");
                return result;
            }
        }
        
        public static void main(String[] args) {
            House house = new HouseOwner();
            //生成动态代理对象
            House houseProxy = (House)Proxy.newProxyInstance(House.class.getClassLoader(), new Class[] {House.class}, 
                    new HouseDynamicProxy(house));
            //执行代理方法
            houseProxy.sale();
        }
    }
    //中介代理售房开始
    //房东售房
    //中介代理售房结束
    

    2)Cglib代理
    JDK自带的代理,需要被代理类实现相关的接口,而如果没有实现接口,该怎么办呢,Cglib就派上用场了。
    我们先来看它的实现方法:

    public class CglibDynamicProxyTest {
        // 售卖房屋抽象
        static interface House {
            void sale();
        }
    
        // 被代理对象
        static class HouseOwner implements House {
            @Override
            public void sale() {
                System.out.println("房东售房");
            }
        }
    
        static class HouseCglibProxy implements MethodInterceptor {
    
            private Object target;
            
            HouseCglibProxy(final Object target){
                this.target = target;
            }
            
            public Object getInstance(final Object target) {
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(target.getClass());
                enhancer.setCallback(this);
                return enhancer.create();
            }
    
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println("中介代理售房开始");
                Object result = method.invoke(target, args);
                System.out.println("中介代理售房结束");
                return result;
            }
        }
    
        public static void main(String[] args) {
            House house = new HouseOwner();
            HouseCglibProxy cglibProxy = new HouseCglibProxy(house);
            HouseOwner houseOwner = (HouseOwner)cglibProxy.getInstance(house);
            houseOwner.sale();
        }
    }
    //中介代理售房开始
    //房东售房
    //中介代理售房结束
    
    • 两种动态代理的区别
    1. JDK动态代理实现代理对象的接口,而Cglib是继承了代理对象
    2. 他们都是运行期间生成字节码,但Cglib更复杂一些,因此在生成大量对象时,效率要低一点
    3. Cglib是通过FastClass机制调用,执行效率要比JDk自带的要高一些
      具体用哪个代理,相信大家都有自己的选择了! -_-

    相关文章

      网友评论

          本文标题:代理模式 ~ 设计模式之七

          本文链接:https://www.haomeiwen.com/subject/ufxqhrtx.html