设计模式--------代理模式

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

 

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

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

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

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

//抽象主题角色
    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("");
    }
}

 

posted @ 2017-04-06 23:02  Topze  阅读(147)  评论(0编辑  收藏  举报