HengYk Blog

个人站

具有浪漫主义情调的理想主义务实青年


Java Reflection R2

反射

1. 静态代理和动态代理

       代理设计模式的原理: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。


       静态代理。


interface ClothFactory {
    void produceCloth();
}

// 代理类
class NikeClothFactory implements ClothFactory {

    @Override
    public void produceCloth() {
        System.out.println("NikeClothFactory");
    }
}

// 被代理类
class NikeProxyFactory implements ClothFactory {

    private NikeClothFactory ncf;

    public NikeProxyFactory(NikeClothFactory ncf) {
        this.ncf = ncf;
    }

    @Override
    public void produceCloth() {
        System.out.println("Receive proxy of Nike");
        ncf.produceCloth();
    }
}

public class TestClothProduct {

    public static void main(String[] args) {
        NikeClothFactory ncf = new NikeClothFactory();
        NikeProxyFactory npf = new NikeProxyFactory(ncf);
        npf.produceCloth();
    }
}

       动态代理。


interface ClothFactory2 {
    void produceCloth();
}

// 被代理类
class NikeFactory implements ClothFactory2 {

    @Override
    public void produceCloth() {
        System.out.println("NikeFactory");
    }
}

// InvocationHandler
class MyInvocationHandler implements InvocationHandler {

    private Object obj; // 被代理类的对象

    public Object blind(Object obj) {
        this.obj = obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(obj, args);
    }
}

public class TestClothProduct2 {

    public static void main(String[] args) {

        // 1.被代理类的对象
        NikeFactory nf = new NikeFactory(); // 被代理对象

        // 2.创建一个实现了InvocationHandler接口的类的对象
        MyInvocationHandler mih = new MyInvocationHandler();

        // 3.调用blind()方法,动态地返回一个代理类的对象。
        ClothFactory2 cf = (ClothFactory2) mih.blind(nf); // 代理对象

        // 4.转到对InvocationHandler接口的实现类的invoke()方法的调用
        cf.produceCloth();
    }
}

2. 面向切面编程

AOP代理:可以在执行目标方法之前、之后插入一些通用处理。


interface Human {
    void info();

    void fly(String str);
}

// 被代理类
class SuperMan implements Human {

    @Override
    public void info() {
        System.out.println("INFO");
    }

    @Override
    public void fly(String str) {
        System.out.println("FLY" + str);
    }
}

class SuperManProxy {

    // 获得代理类
    public static Object getProxyObject(Object object) {
        MyInvocationHandler mih = new MyInvocationHandler();
        mih.setObject(object); // 注意这里的小细节。

        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), mih);
    }
}

// InvocationHandler
class MyInvocationHandler implements InvocationHandler {

    private Object object;

    public void setObject(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        HumanUtil humanUtil = new HumanUtil();
        humanUtil.methodOne();

        Object obj = method.invoke(object, args);

        humanUtil.methodTwo();

        return obj;
    }
}

class HumanUtil {
    public void methodOne() {
        System.out.println("method-1");
    }

    public void methodTwo() {
        System.out.println("method-2");
    }
}

public class TestAOP {

    public static void main(String[] args) {

        SuperMan sm = new SuperMan();
        Human h = (Human) SuperManProxy.getProxyObject(sm);

        h.info();

        System.out.println();

        h.fly("higher");

        /*
        method-1
        INFO
        method-2

        method-1
        FLYhigher
        method-2
         */
    }
}
代码下载参见https://github.com/HengYk/Reflection