zoukankan      html  css  js  c++  java
  • 设计模式代理模式

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

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

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

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

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

    //抽象主题角色
        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<T>{
        public static <T> 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> 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("");
        }
    }
  • 相关阅读:
    37.Spring-事务控制.md
    35.Spring-jdbc支持.md
    29.Hibernate-二级缓存和session管理.md
    28.Hibernate-HQL查询.md
    27.Hibernate-缓存和懒加载.md
    26.Hibernate-主键和映射.md
    25.Hibernate-配置文件.md
    24.Hibernate-各种类型的查询.md
    MarkDown学习记录
    gitbook使用
  • 原文地址:https://www.cnblogs.com/maple92/p/6675911.html
Copyright © 2011-2022 走看看