博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式--------代理模式
阅读量:5159 次
发布时间:2019-06-13

本文共 5839 字,大约阅读时间需要 19 分钟。

代理模式:为其他对象提供一种代理以控制对这个对象的访问。

 

最简单的代理模式,分为三种角色:

抽象主题角色:代理类与被代理共同实现的接口,内部定义了最普通的业务类型。

具体主题角色:被代理类,具体实现接口的方法。

代理主题角色:代理类,继承主题接口,并生成与被代理类方法名一致的方法,并且调用被代理类的方法。

//抽象主题角色    public interface ISubject{        //具体业务方法        public void method();    }    //具体主题角色    public class Subject implements ISubject{        public void method(){            //业务方法        }    }    //代理主题角色    public class SubjectProxy implements ISubject{        private ISubject subject = null;        public SubjectProxy(ISubject subject){             this.subject = subject;       }        public void method(){            this.before();            subject.method;            this.after();        }        private void before(){            //前置增强业务逻辑        }        private void after(){            //后置增强逻辑        }    }        //调用    public static void main(String args[]){        ISubject subject = new Subject();        ISubject proxy = new SubjectProxy(subject);        proxy.method();    }

 

代理模式的扩展

1、普通代理

  调用者只能调用代理对象,并且只知道代理对象类型,不知被代理对象类型。

//普通代理    //抽象主题角色        public interface ISubject{            //具体业务方法            public void method();        }        //具体主题角色        public class Subject implements ISubject{                        public Subject(ISubject subject) throws Exception{                if(subject == null){                    throw new Exception("");                }else{                                    }            }                        public void method(){                //业务方法            }        }        //代理主题角色        public class SubjectProxy implements ISubject{            private ISubject subject = null;            public SubjectProxy(){                try{                    subject = new Subject(this);                }catch(Exception e){                                    }            }            public void method(){                this.before();                subject.method;                this.after();            }            private void before(){                //前置增强业务逻辑            }            private void after(){                //后置增强逻辑            }        }                //调用        public static void main(String args[]){            ISubject proxy = new SubjectProxy();            proxy.method();        }

2、强制代理

必须通过实例化被代理对象,然后通过被代理对象的指定的代理对象进行方法调用。

// 强制代理    // 抽象主题角色    public interface ISubject {        // 具体业务方法        public void method();        // 找到代理类        public ISubject getProxy();    }    // 具体主题角色    public class Subject implements ISubject {        private ISubject proxy = null;        public ISubject getProxy() {            this.proxy = new Subject(this);            return this.proxy;        }        public void method() {            if (this.isProxy()) {                // 业务方法            } else {            }        }        // 校验是否是代理访问        private boolean isProxy() {            if (this.proxy == null) {                return false;            } else {                return true;            }        }    }    // 代理主题角色    public class SubjectProxy implements ISubject {        private ISubject subject = null;        public SubjectProxy(ISubject subject) {            this.subject = subject;        }        public void method(){            this.before();            subject.method();            this.after();        }        private void before() {            // 前置增强业务逻辑        }        private void after() {            // 后置增强逻辑        }                public ISubject getProxy(){            return this;        }    }    // 调用    public static void main(String args[]) {        ISubject subject = new Subject();        ISubject proxy = subject.getProxy();        proxy.method();    }

 

代理类不仅仅可以实现主题接口,也可以实现其他接口完成不同的任务,而且代理的目的是在目标对象方法的基础上作增强,这种增强的本质通常就是对目标对象的方法进行拦截和过滤。

 

动态代理

动态代理是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。使用JDK提供的动态代理接口InvocationHandler对被代理类的方法进行代理。

//抽象主题public interface Subject{    //业务操作方法    public void doSomething(String str);}
//真实主题public class RealSubject implements Subject{    //业务操作    public void doSomething(String str){        System.out.println("do something --> " + str);    }}

真实主题实现主题类接口

//动态代理的Handler类public class MyInvocationHandle implements InvocationHandle {    // 被代理对象    private Object target = null;    // 通过构造函数传递一个对象    public MyInvocationHandle(Object target) {        this.target = target;    }    // 代理方法 可在此方法中对原方法进行增强    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        // 执行被代理方法        return method.invoke(this.target, args);    }}

所有的动态代理实现方法都通过invoke的方法调用。

 

//动态代理类public class DynamicProxy
{ public static
T newProxyInstance(ClassLoader loader,Class
[] interfaces,InvocationHandler h){ //寻找JoinPoint连接点,AOP框架使用元数据定义 if(true){ //通知类的方法调用 (new BeforeAdvice()).exec(); } return (T)Proxy.newProxyInstance(loader, interfaces, h); }}//具体业务的动态代理类public class SubjectDynamicProxy extends DynamicProxy{ public static
T newProxyInstance(Subject subject){ //获取ClassLoader ClassLoader loader = subject.getClass().getClassLoader(); //获取接口数组 Class
[] classes = subject.getClass().getInterfaces(); //获取hander InvocationHandler handler = new MyInvocationHandler(subject); return newProxyInstance(loader,classes,handler); }}
调用 newProxyInstance(c.getClassLoader(),c.getInterfaces,InvocationHandler h)方法, 重新生成了一个对象,c.getInterfaces找到了类的所有接口,然后实现了接口的所有方法,但是方法都是空的,这些方法都由InvocationHandle方法来接管。
//具体调用public class Client{    public static void main(String[] args){                Subject subject = new RealSubject();                Subject proxy = SubjectDynamicProxy.newProxyInstance(subject);                proxy.doSomething("");    }}

 

转载于:https://www.cnblogs.com/maple92/p/6675911.html

你可能感兴趣的文章
摘抄详细的VUE生命周期
查看>>
javascript高级程序设计---js事件思维导图
查看>>
sprint计划会议
查看>>
读《构建之法-软件工程》第四章有感
查看>>
使用 Printf via SWO/SWV 输出调试信息
查看>>
.net 分布式架构之分布式锁实现(转)
查看>>
吴恩达机器学习笔记 —— 3 线性回归回顾
查看>>
Bouncy Castle内存溢出
查看>>
多线程_java多线程环境下栈信息分析思路
查看>>
机器学习数学【1】
查看>>
Problem E: Automatic Editing
查看>>
Java数组排序
查看>>
SpringBoot 使用 MyBatis 分页插件 PageHelper 进行分页查询
查看>>
《DSP using MATLAB》Problem 6.17
查看>>
微信公众平台开发实战Java版之如何网页授权获取用户基本信息
查看>>
一周TDD小结
查看>>
(三)建筑物多边形化简系列——去除冗余点
查看>>
Spring Boot Oauth2缓存UserDetails到Ehcache
查看>>
sizeof与strlen的用法
查看>>
2017 ICPCECPC 邀请赛 F,D,E, I 题解
查看>>