设计模式之代理

来源:互联网 发布:谷饶淘宝村 编辑:程序博客网 时间:2024/06/05 11:37

为某一个对象创建一个代理对象,这个代理对象在调用方法的时候实际内部也是调用的被代理对象的方法,只是允许在调用被代理对象前后增加代理对象自己的逻辑,比如日志输出,权限检查,事物控制等。代理模式又分为静态代理与动态代理。

静态代理

静态代理就是以实际编码的方式编写出一个代理类来通过继承或者聚合的方式与被代理类关联。

继承实现

被代理类与代理类之间通过继承方式关联。此方式不够灵活,如果需要增加多层代理逻辑,继承实现起来就比较麻烦。建议用聚合方式实现。

被代理类:

package com.legend.StaticProxy;public class Orange {    public void eat(){        System.out.println("我在吃橘子");    }}

代理类(继承了被代理类):

package com.legend.StaticProxy;public class OrangeProxy extends Orange {    @Override    public void eat(){        System.out.println("before do sth");        super.eat();        System.out.println("after do sth");    }}

测试类:

package com.legend.StaticProxy;public class OrangeProxy extends Orange {    @Override    public void eat(){        System.out.println("before do sth");        super.eat();        System.out.println("after do sth");    }}

聚合实现

被代理类与代理类之间通过聚合方式关联。

接口:
package com.legend.StaticProxy;

public interface Fruit {    void eat();}

被代理类:

package com.legend.StaticProxy;public class Apple implements Fruit {    public void eat() {        System.out.println("我在吃苹果");     }}

代理类1:

package com.legend.StaticProxy;public class AppleProxy1 implements Fruit {    private Fruit apple;    public AppleProxy1(Fruit apple){        this.apple = apple;    }    public void eat() {        System.out.println("吃苹果之前");        apple.eat();        System.out.println("吃苹果之后");    }}

代理类2:

package com.legend.StaticProxy;public class AppleProxy2 implements Fruit {    private Fruit apple;    public AppleProxy2(Fruit apple){        this.apple = apple;    }    public void eat() {        System.out.println("洗苹果");        apple.eat();        System.out.println("扔果核");    }}

测试类:

package com.legend.StaticProxy;import org.junit.Test;import com.legend.StaticProxy.Apple;import com.legend.StaticProxy.AppleProxy1;import com.legend.StaticProxy.Fruit;public class AppleProxyTest {    @Test    public void aaaTestCase(){        Apple apple = new Apple();        //Fruit fruitProxy1 = new AppleProxy1(apple);        //Fruit fruit = new AppleProxy2(fruitProxy1);        Fruit fruitProxy2 = new AppleProxy2(apple);        Fruit fruit = new AppleProxy1(fruitProxy2);        fruit.eat();    }}

动态代理

动态代理则是通过反射在程序运行期间动态的为被代理类创建匿名的代理对象。

JDK Proxy

被代理类必须从实现接口,如果没有实现接口,需要选用Cglib

接口:

package com.legend.DynamicProxy;public interface Fruit {    void eat();    void clean();}

被代理类:

package com.legend.DynamicProxy;public class Apple implements Fruit {    public void eat() {        System.out.println("我在吃苹果");    }    public void clean() {        System.out.println("我在洗苹果");    }}

代理类处理器:

package com.legend.DynamicProxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class AppleHandler implements InvocationHandler {    private Object target;    public AppleHandler(Object target){        this.target = target;    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        Object result = null;        System.out.println("do before...");        result =  method.invoke(target, args);        System.out.println("do after...");        return result;    }}

测试类:

package com.legend.DynamicProxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import org.junit.Test;public class AppleProxyTest {        @Test        public void appleTestCase(){                Apple apple = new Apple();                InvocationHandler appleHandle = new AppleHandler(apple);                Fruit fruitProxy = (Fruit)Proxy.newProxyInstance(Fruit.class.getClassLoader(), Apple.class.getInterfaces(), appleHandle);                fruitProxy.eat();                fruitProxy.clean();        }        /*         * 匿名代理类可能的实现方式         * public class $fruitProxy implements Fruit{         *      public Object eat(){         *          Method m = Fruit.getClass.getMethod("eat");         *          Object result = appleHandle.invoke(this,m,null);         *          return result;         *      }          * }         */}

Cglib

0 0
原创粉丝点击