• 设计模式之代理模式


    • 代理模式(Proxy pattern)

      • 抽象角色:定义代理角色和真实角色的公共对外方法
      • 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用
      • 代理角色:实现抽象,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作
    • 代理对象和目标对象都要实现指定的接口

    • 代理对象要包含目标对象

    • 代理对象对照目标对象进行增强

    静态代理(static proxy)

    • 抽象角色
    package designmode.proxy.staticproxy;
    public interface Star {
        /**
         * 面谈
         */
        void confer();
        /**
         * 签合同
         */
        void signContract();
        /**
         * 订票
         */
        void bookTicket();
        /**
         * 唱歌
         */
        void sing();
        /**
         * 收尾款
         */
        void collectMoney();
    }
    • 目标对象
    package designmode.proxy.staticproxy;
    public class RealStar implements Star{
        @Override
        public void confer() {
    
        }
        @Override
        public void signContract() {
    
        }
        @Override
        public void bookTicket() {
    
        }
        @Override
        public void sing() {
            System.out.println("周杰伦本人唱歌");
    
        }
        @Override
        public void collectMoney() {
    
        }
    }
    • 代理对象
    package designmode.proxy.staticproxy;
    public class ProxyStar implements Star{
    
        private Star star;
    
        public ProxyStar(Star star) {
            this.star = star;
        }
        @Override
        public void confer() {
            System.out.println("面谈");
        }
        @Override
        public void signContract() {
            System.out.println("签合同");
    
        }
        @Override
        public void bookTicket() {
            System.out.println("订票");
    
        }
        @Override
        public void sing() {
            star.sing();
    
        }
        @Override
        public void collectMoney() {
            System.out.println("收尾款");
    
        }
    }
    • 测试
    package designmode.proxy.staticproxy;
    public class Client {
        public static void main(String[] args) {
            Star real = new RealStar();
            Star proxy = new ProxyStar(real);
            proxy.confer();
            proxy.signContract();
            proxy.bookTicket();
            proxy.sing();
            proxy.collectMoney();
        }
    }

    • 动态代理(jdk代理)

      • 抽象角色

    package designmode.proxy.dynamicproxy;
    public interface Star {
        /**
         * 面谈
         */
        void confer();
        /**
         * 签合同
         */
        void signContract();
        /**
         * 订票
         */
        void bookTicket();
        /**
         * 唱歌
         */
        void sing();
        /**
         * 收尾款
         */
        void collectMoney();
    }
    • 真实角色

    package designmode.proxy.dynamicproxy;
    public class RealStar implements Star{
        @Override
        public void confer() {
            System.out.println("和经纪人面谈");
        }
        @Override
        public void signContract() {
            System.out.println("和经纪公司签合同");
        }
        @Override
        public void bookTicket() {
            System.out.println("订票");
        }
        @Override
        public void sing() {
            System.out.println("周杰伦本人唱歌");
    
        }
        @Override
        public void collectMoney() {
            System.out.println("付尾款");
        }
    }
    • 处理器类

    package designmode.proxy.dynamicproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class StarHandler implements InvocationHandler{
    
        private Object realStar;
    
    
        public StarHandler(ObjectrealStar) {
            this.realStar = realStar;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object obj = null;
            System.out.println("面谈,签合同,预付款,订票");
            if(method.getName().equals("sing")) {
                obj = method.invoke(realStar, args);
            }
            System.out.println("收尾款");
            return obj;
        }
    
    }
    
    • 测试

    package designmode.proxy.dynamicproxy;
    import java.lang.reflect.Proxy;
    public class Client {
        public static void main(String[] args) {
            Star realStar = new RealStar();
            StarHandler handler = new StarHandler(realStar);
            Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {Star.class}, handler);
            proxy.sing();
        }
    }

    • CGLIB动态代理

      • 利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

    • 目标对象

    package designmode.proxy.cglib;
    public class TeacherDao {
    
        public void teach() {
            System.out.println("老师授课中,我是cglib代理,不需要实现接口");
        }
    }
    • 代理实现

    package designmode.proxy.cglib;
    import java.lang.reflect.Method;
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    public class ProxyFactory implements MethodInterceptor{
    
        private Object target;
    
        public ProxyFactory(Object target) {
            this.target = target;
        }
    
        // 返回一个代理对象,是target对象的代理对象
        public Object getProxyInstance() {
            // 创建一个工具类
            Enhancer enhancer = new Enhancer();
            //设置父类
            enhancer.setSuperclass(target.getClass());
            // 设置回调函数
            enhancer.setCallback(this);
            //创建子类对象,即代理对象
            return enhancer.create();
        }
    
        //重写intercept方法,会调用目标对象的方法
        @Override
        public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
            System.out.println("Cglib代理模式开始");
            Object returnValue = arg1.invoke(target, arg2);
            System.out.println("Cglib代理提交");
            return returnValue;
        }
    
    }
    • 测试

    package designmode.proxy.cglib;
    public class Client {
        public static void main(String[] args) {
            TeacherDao target = new TeacherDao();
            TeacherDao proxy =(TeacherDao) new ProxyFactory(target).getProxyInstance();
            proxy.teach();
        }
    }

    注意:cglib支持jdk8以下的版本,8以上的版本报类型转换错误

    参考资料:
    https://www.jianshu.com/p/46d092bb737d





  • 相关阅读:
    torch上疑问用法总结
    matplotlib库介绍
    java学习总结
    java高级并发编程实战
    java的spi思想--打破双亲委派模型的操作
    linux设置静态ip步骤流程
    jvm调优参数设置
    jvisualvm插件的基本使用
    jvm常见的gc种类
    jvm调优案例与步骤
  • 原文地址:https://www.cnblogs.com/baiyifengyun/p/14288611.html
Copyright © 2020-2023  润新知