JAVA23种设计模式之代理模式(三)动态代理模式

动态代理
动态代理又叫做JDK代理、接口代理。其和静态代理的区别是不需要实现接口。而是直接利用JDK的API动态的在内存中创建代理对象。
在JDK中生成代理对象的API,存在于java.lang.reflect.Proxy这个包内。JDK实现代理只需要使用
newProxyInstance方法即可。调用方式如下:

/**
 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
 */
static ObjectnewProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

loader:获取当前对象的类加载器,一般方法是固定的。
interfaces:目标对象实现的借口类型,一般用泛型确认类型。
h:事件处理,执行目标对象的方法时,会触发事件处理方法,会把当前执行目标对象的方法作为参数传入。
例如:

Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class },handler);

示例代码:
对象的行为接口:

public interface Caculate {
    int add(int a,int b) ;
    int sub(int a,int b) ;
    int mul(int a,int b) ;
    int div(int a,int b) ;
}

目标业务对象类:

public class CaculateImpl implements Caculate {
    @Override
    public int add(int a, int b)  {
        return a+b;
    }
    @Override
    public int sub(int a, int b) {
        return a-b;
    }
    @Override
    public int mul(int a, int b) {
        return a*b;
    }
    @Override
    public int div(int a, int b) {
        return a/b;
    }
}

生成代理对象的代理类:

public class ProxyFactory {
    //目标对象
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }
    //动态代理模式的关键性代码
    public Object getProxyInstance(){
        return  Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //在转调具体目标对象之前,可以执行一些功能处理
                print();
                System.out.println(">>>>>>>>start"+"||"+method.getName());
                //执行目标方法
                Object returnValue  =   method.invoke(target,args);
                //在转调具体目标对象之前,可以执行一些功能处理
                System.out.println(">>>>>>>>end");
                return returnValue;
            }
        });
    }
    public void print(){
        System.out.println(">>>>>>>>>>You are not alone!");
    }
}

测试主函数:

public class Main {
    public static void main(String[] args) {
        //目标对象
        Caculate caculate = new CaculateImpl();
        System.out.println(caculate.getClass());
        Caculate caculate1 = (Caculate) new ProxyFactory(caculate).getProxyInstance();
        System.out.println(caculate1.getClass());
        int result = 0;
        result = caculate1.add(1,2);
        System.out.println(">>>>>>>>>>>>>>>>>"+result);
    }
}

编写动态代理模式的步骤:

  1. 创建接口和实现接口的目标类,
  2. 实现InvocationHandler接口,重写invoke方法。
  3. 调用proxy的静态方法newProxyInstance方法生产代理实例。
  4. 使用新生成的代理实例调用目标对象的方法。
    优缺点:
    优点:
    代理对象无需实现接口,不需要写过多的代理类。如果增加方法也不需要在维护目标对象和代理对象,只需要在事件处理器中添加方法判断即可。
    缺点:
    目标对象要求一定要实现接口。否则就无法使用动态代理。
发布了62 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/system_obj/article/details/87927080