• 代理模式


    模式介绍

    在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

    模式优点

    1、职责清晰。
    2、高扩展性。

    模式缺点

    1、由于在客户端和真实对象之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
    2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

    使用场景

    1、远程代理。
    2、虚拟代理。
    3、保护(Protect or Access)代理。
    4、Cache代理。
    5、防火墙(Firewall)代理。
    6、同步化(Synchronization)代理。
    7、智能引用(Smart Reference)代理。

    系统建模

    1、下面分别实现三种代理模式。

    系统实现

    静态代理:代理模式中最简单的一种实现方式。

    /**
     * 老师接口
     */
    public interface ITeacher {
        public void teach();
    }
    
    /**
     * 老师实现类
     */
    public class Teacher implements ITeacher {
    
        @Override
        public void teach(){
            System.out.println("今天我们学习如何打野更有效率!");
        }
    }
    
    /**
     * 老师代理
     */
    public class TeacherProxy {
        private ITeacher teacher;
    
        public TeacherProxy(ITeacher teacher){
            this.teacher = teacher;
        }
    
        public void teach(){
            System.out.println("代理开始了!");
            teacher.teach();
            System.out.println("代理结束了!");
        }
    }
    
    /**
     * 客户端
     */
    public class Client {
        public static void main(String args[]){
           TeacherProxy proxy = new TeacherProxy(new Teacher());
           proxy.teach();
        }
    }
    结果:
    代理开始了!
    今天我们学习如何打野更有效率!
    代理结束了!
    

    动态代理:动态代理又称JDK代理或接口代理,被代理对象必须实现接口。

    /**
     * 老师接口
     */
    public interface ITeacher {
        public void teach();
    }
    
    /**
     * 老师实现类
     */
    public class Teacher implements ITeacher {
    
        @Override
        public void teach(){
            System.out.println("今天我们学习如何打野更有效率!");
        }
    }
    
    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(){
            ClassLoader classLoader = target.getClass().getClassLoader();
            Class<?>[] interfaces = target.getClass().getInterfaces();
            return Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("JDK代理开始!");
                    Object returnObject = method.invoke(target, args);
                    return returnObject;
                }
            });
        }
    }
    
    /**
     * 客户端
     */
    public class Client {
        public static void main(String args[]){
            ITeacher teacher = new Teacher();
            ITeacher proxyTeacher = (ITeacher)new ProxyFactory(teacher).getProxyInstance();
            proxyTeacher.teach();
        }
    }
    结果:
    JDK代理开始!
    今天我们学习如何打野更有效率!
    

    Cglib代理:针对代理的类, 动态生成一个子类, 然后子类覆盖代理类中的方法, 如果是final修饰的方法,则不会被重写。

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.5</version>
    </dependency
    
    /**
     * 老师类
     */
    public class Teacher {
        public void teach(){
            System.out.println("今天我们学习如何打野更有效率!");
        }
    }
    
    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;
        }
        
        public Object getProxy() {
            Enhancer en = new Enhancer();
            en.setSuperclass(target.getClass());  
            en.setCallback(this);     
            return en.create();
        }
    
        @Override  
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("Cglib代理开始了!");
            Object returnValue = proxy.invokeSuper(obj, args);
            return returnValue;
        }
    }
    
    /**
     * 客户端
     */
    public class Client {
        public static void main(String[] args) {
            ProxyFactory teacherProxy = new ProxyFactory(new Teacher());
            Teacher teacher = (Teacher)teacherProxy.getProxy();
            teacher.teach();
        }
    }
    结果:
    Cglib代理开始了!
    今天我们学习如何打野更有效率!
    
  • 相关阅读:
    java矩阵运算包ujmp中的一些小示例和注意事项
    CSS文字段落排版常用设置
    HTML中标签元素的分类
    三种CSS样式-内联、嵌入、外部
    MySQL常用命令
    解决谷歌浏览器在win8下没有注册类的问题
    转:jQuery.lazyload详解使用方法
    php取整
    限制表单Input的长度,当达到一定长度时不能再输入
    滑动后定位
  • 原文地址:https://www.cnblogs.com/feiqiangsheng/p/12209199.html
Copyright © 2020-2023  润新知