代理模式

  1. 动态代理:基于反射机制。

  2. 什么是动态代理?

  3. 动态代理能做什么?

  4. 代理模式:客户端,间接地通过代理对象,但最终目标还是被代理对象(控制对目标对象的访问,型成物理隔离)。

  5. 代理模式的作用

    1. 功能增强:在原有的功能上,增加额外能力。
    2. 控制访问:目标对象不允许直接访问。
  6. 实现方式:

    1. 静态代理:代理类是手动实现的,自己创建一个类,标识代理类。
    2. 优点:实现简单,易于理解。
    3. 缺点:目标对象增加,代理对象会成倍增加;接口新增或修改方法,所有实现类都要变更。
  7. 动态代理:在程序执行时(通常是启动阶段),利用反射机制,创建代理对象,并动态地制定目标对象。其实动态代理提供了一种不用手动创建类,就能产生代理对象的能力。

  8. 静态代理Demo:

package comg.yang.httpstest;

/**
 * @description:
 * @author: Yang JianXiong
 * @since: 2016/8/25
 */
public class StaticProxyDemo {

    public static void main(String[] args) {
        SellAble proxySeller = new ProxySeller(new TargetSeller());
        proxySeller.sell(100F);
    }

}

/**
 * 售卖能力接口
 */
interface SellAble {

    void sell(float price);

}

class ProxySeller implements SellAble {

    private final SellAble targetSeller;

    @Override
    public void sell(float price) {
        this.targetSeller.sell(this.cut(price));
    }

    /**
     * 中介盘剥
     *
     * @param price
     * @return
     */
    private float cut(float price) {
        float result = price * 0.8F;
        System.out.printf("中介盘剥:%f元\n", price - result);
        return result;
    }

    public ProxySeller(SellAble targetSeller) {
        this.targetSeller = targetSeller;
    }

}

class TargetSeller implements SellAble {

    @Override
    public void sell(float price) {
        System.out.printf("最终收入:%f元", price);
    }
}

  1. 通过JDK反射机制执行方法:
package comg.yang.httpstest;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @description:
 * @author: Yang JianXiong
 * @since: 2016/8/25
 */
public class MethodReflectDemo {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 1.通过方法签名(方法名 + 参数列表),通过反射获取在接口中声明的方法对象
        Method sayHello = HelloService.class.getMethod("sayHello", String.class);

        // 2.通过给方法对象传递不同的目标对象和参数,执行不同的实现。
        sayHello.invoke(new HelloServiceImpl(), "张三");
        sayHello.invoke(new HelloServiceImpl_0(), "张三");
    }

}

interface HelloService {

    void sayHello(String name);

}

class HelloServiceImpl implements HelloService {

    @Override
    public void sayHello(String name) {
        System.err.printf("hello:%s \n", name);
    }
}

class HelloServiceImpl_0 implements HelloService {

    @Override
    public void sayHello(String name) {
        System.err.printf("hello_0:%s \n", name);
    }
}
  1. JDK动态代理Demo
package comg.yang.httpstest;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @description:
 * @author: Yang JianXiong
 * @since: 2016/8/25
 */
public class DynamicProxyDemo {

    public static void main(String[] args) {
        SingAble jay = new Jay();
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(jay);
        SingAble proxyInstance = (SingAble) Proxy.newProxyInstance(jay.getClass().getClassLoader(), jay.getClass().getInterfaces(), myInvocationHandler);

        // 唱歌
        proxyInstance.sing("500 miles");
        // 跑步
        proxyInstance.go("5000 miles");
    }

}

interface SingAble {

    void sing(String songName);

    void go(String songName);

}

class Jay implements SingAble {

    @Override
    public void sing(String songName) {
        System.out.printf("周杰伦在唱歌:%s\n", songName);
    }

    @Override
    public void go(String songName) {
        System.out.printf("周杰伦在走路:%s\n", songName);
    }
}

class MyInvocationHandler implements InvocationHandler {

    private final Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.err.println("额外功能");
        return method.invoke(this.target, args);
    }
}
posted @ 2023-03-26 18:55  JaxYoun  阅读(18)  评论(0编辑  收藏  举报