• 动态代理Java实现


    思考:在IBuyWatermelon添加一个方法selectWatermelon()

    静态代理中需要在RealSubject中实现该方法,而且Proxy也要实现该方法调用RealSubject中的实现,如果再增加10个方法还是得这样操作,导致大量的代码重复。

    现在来看动态代理(顾名思义,是在运行时才形成的代理对象,不像静态代理在编译时就载入代理对象)。

    生成动态代理的方法有很多: JDK中自带的动态代理java.lang.reflect.*, CGlib等

    下面的例子是JDK中自带的动态代理java.lang.reflect.*

    IBuyWatermelon():接口

    package com.maggie.dynamicproxy;
    
    public interface IBuyWatermelon {
        //代理事件
        public abstract String buyWatermelon();
        
        public abstract void selectWatermelon();
    }

    BuyWatermelonImpl:实现类

    package com.maggie.dynamicproxy;
    
    //可理解成被代理者
    public class BuyWatermelonImpl implements IBuyWatermelon {
    
        private Supermarket supermaket;
        
        public BuyWatermelonImpl(Supermarket supermaket) {
            super();
            this.supermaket = supermaket;
        }
    
        @Override
        public String buyWatermelon() {
            System.out.println("在"+supermaket.getName()+" 买西瓜");
            return "watermelon";
        }
    
        @Override
        public void selectWatermelon() {
            System.out.println("选择无籽西瓜");
        }
    
    }

    ProxyFactory:代理对象类(核心代码)

    package com.maggie.dynamicproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyFactory {
         //维护一个目标对象
        private Object target;
        public ProxyFactory(Object target){
            this.target=target;
        }
    
       //给目标对象生成代理对象
        public Object getProxyInstance(){
            //动态代理的核心,涉及到反射
            return Proxy.newProxyInstance(
                    target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                //执行目标对象方法
                                Object returnValue = method.invoke(target, args);
                                return returnValue;
                        }
                    }
            );
        }
    
    }

    客户端调用

    package com.maggie.dynamicproxy;
    
    
    public class Main {
        public static void main(String[] args) {
            Supermarket zhaoLiu = new Supermarket();
            zhaoLiu.setName("赵六超市");
            IBuyWatermelon target  = new BuyWatermelonImpl(zhaoLiu);//被代理的对象
            
            
            //创建代理对象
            IBuyWatermelon hourskeeper = (IBuyWatermelon) new ProxyFactory(target).getProxyInstance();
            
            hourskeeper.buyWatermelon();
            hourskeeper.selectWatermelon();
            
        }
    }

    输出

    在赵六超市 买西瓜
    选择无籽西瓜

    现在就算IBuyWatermelon的方法再怎么增加,也只需要在BuyWatermelonImpl实现,就可以在客户端调用,不会出现大量的重复代码。

    从静态代理到动态代理都围绕着卖瓜事件,为了前后方便比较,但是动态代理并没完,里面的源码机制才是核心关键

    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)这个方法是整个动态代理实现的关键

  • 相关阅读:
    Spring Aop
    Java 内存分配
    wrapper class (Integer 为例)
    asp.net mvc 中"未找到路径“/favicon.ico”的控制器或该控制器未实现 IController。"
    .Net反射机制
    设计模式系列一创建型之(抽象工厂模式)
    设计模式系列一创建型之(单件模式)
    设计模式系列二结构型之(装饰者模式)
    设计模式系列二结构型之(策略者模式)
    设计模式系列一创建型模式之(简单工厂VS工厂方法)
  • 原文地址:https://www.cnblogs.com/maggiejyt/p/7569123.html
Copyright © 2020-2023  润新知