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

    静态代理

    package proxy;
    /*
    @author zsben
    @create 2020-01-06 23:25
    */
    
    interface ClothFactory{
        void produceCloth();
    }
    //代理类
    class ProxyClothFactory implements ClothFactory{
    
        private ClothFactory factory;
    
        public ProxyClothFactory(ClothFactory factory){
            this.factory = factory;
        }
    
        @Override
        public void produceCloth() {
            System.out.println("代理工厂做一些准备工作");
            factory.produceCloth();
            System.out.println("代理工厂做一些收尾工作");
        }
    }
    //被代理类
    class NikeClothFactory implements ClothFactory{
    
        @Override
        public void produceCloth() {
            System.out.println("Nike 开始生产产品");
        }
    }
    
    public class StaticProxyTest {
        public static void main(String[] args) {
            NikeClothFactory nike = new NikeClothFactory();
            ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nike);
            proxyClothFactory.produceCloth();
        }
    }

    动态代理

    package proxy;
    /*
    动态代理的举例
    AOP:面向切面
    @author zsben
    @create 2020-01-06 23:37
    */
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    interface Human{
    
        String getBelief();
    
        void eat(String food);
    }
    class HumanUtil{
        public void method1(){
            System.out.println("==================通用方法一==================");
        }
        public void method2(){
            System.out.println("==================通用方法二==================");
        }
    }
    
    //被代理类
    class SuperMan implements Human{
    
        @Override
        public String getBelief() {
            return "I believe I can fly!";
        }
    
        @Override
        public void eat(String food) {
            System.out.println("我喜欢吃"+food);
        }
    }
    /*
    * 要想实现动态代理,需要解决的问题:
    * 问题一:如何根据加载到内存中的被代理类,动态创建一个代理类和其代理对象
    * 问题二:当通过代理类的对象调用方法时,如何动态调用被代理类中的同名方法
    *
    * */
    
    class ProxyFactory{
        //调用此方法返回一个代理类的对象,解决问题一
        public static Object getProxyInstance(Object obj){//obj:被代理类的对象
            MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
    
            myInvocationHandler.bind(obj);
    
            //返回代理类对象
            return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                    obj.getClass().getInterfaces(),myInvocationHandler);
        }
    }
    class MyInvocationHandler implements InvocationHandler{
    
        private Object obj;//需要使用被代理类的对象进行赋值
    
        public void bind(Object obj){
            this.obj=obj;
        }
    
        //当我们通过代理类对象调用方法a时,就会自动调用如下方法:invoke
        //将被代理类要执行的方法a的功能声明在invoke方法中
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println("开始代理");
            HumanUtil util = new HumanUtil();
            util.method1();
    
            //method:代理类对象调用的方法,此方法也就作为被代理类对象要调用的方法
            Object returnValue = method.invoke(obj, args);
    
    
            util = new HumanUtil();
            util.method2();
            System.out.println("结束代理");
            //上述方法的返回值就作为invoke的返回值
            return returnValue;
        }
    }
    
    
    public class ProxyTest {
        public static void main(String[] args) {
            SuperMan superMan = new SuperMan();
            //proxyInstance : 代理类的对象
            Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
    
            //通过代理类对象调用方法时,会自动的调用被代理类中同名方法
            String string = proxyInstance.getBelief();
            System.out.println(string);
    
            // 其实是交给MyInvocationHandler类的invoke执行了
            // obj参数就是superMan,args[]参数就是eat方法的参数列表
            proxyInstance.eat("四川麻辣烫");
    
            System.out.println("*****************************************************");
            System.out.println("用静态例子里的被代理类");
            NikeClothFactory nikeClothFactory = new NikeClothFactory();
            ClothFactory proxyInstance1 = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory);
            proxyInstance1.produceCloth();
    
        }
    }
  • 相关阅读:
    设计模式概述
    Android之.9.png图片的制作与使用
    2015-4-3~2015-5-28 第四届全国大学生软件设计大赛《解密陌生人》项目总结
    排序算法之快速排序
    AsyncTask那些事(更新中...)
    经典Android面试题
    import第三方库的头文件找不到的错误
    点击某个按钮在tableView某个位置动态插入一行cell
    NSUserDefaults:熟悉与陌生(转)
    更改UIsearchbar 的背景和cancel按钮(转)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12160537.html
Copyright © 2011-2022 走看看