java反射系七之动态代理

一.概念认知

 

 静态代理:

package staticProxy;
//静态代理模式
//接口
interface ClothFactory{
    void productCloth();
}
//创建被代理类
class NikeClothFactory implements ClothFactory{

    @Override
    public void productCloth() {
        System.out.println("Nike生产了一批衣服");
    }
    
}
//创建代理类
class ProxyFactory implements ClothFactory{
    ClothFactory cf;
    public  ProxyFactory(ClothFactory cf) {
        this.cf=cf;
    }
    @Override
    public void productCloth() {
        System.out.println("收取代理费1000$");
        cf.productCloth();
    }
    
}

动态代理:

package staticProxy;

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

//动态代理的使用
interface Subject{
    void action();
}
//被代理类
class RealSubject implements Subject{
    @Override
    public void action() {
        System.out.println("我是被代理类,么么哒~");
    }    
}
//凡是涉及到动态代理的都要实现InvocationHandler接口
class MyInvocationHandler implements InvocationHandler{
    //实现了接口的被代理类的对象的声明
    Object obj;
    public Object blind(Object obj) {
        this.obj=obj;
        /*
         * obj.getClass().getClassLoader()-->和被代理类的加载器一致
         * obj.getClass().getInterfaces()-->和被代理类的实现接口一致
         * this-->代表MyInvocationHandler
         * 1.给被代理的对象实例化;2.返回一个代理类的对象
         */       
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                  obj.getClass().getInterfaces(), this);
    }
    //当通过代理类的对象发起被重写的方法的调用时,都会转化为对如下的invoke方法的调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //method方法的返回值是returnValue
        Object returnValue = method.invoke(obj, args);
        return returnValue;
    }
    
}
public class TestProxy {
    public static void main(String[] args) {
        //1.被代理类的对象
        RealSubject real = new RealSubject();
        //2.创建一个实现了InvacationHandler接口的类的对象
        MyInvocationHandler handler = new MyInvocationHandler();
        //3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象
        Object obj = handler.blind(real);
        //此时sub就是代理类的对象
        Subject sub = (Subject)obj;
        //转到对InvacationHandler接口的实现类的invoke方法的调用
        sub.action();
        /*
         * 程序分析:blind方法使得代理类实现了和被代理类一样的接口
         * 所以返回的是代理类对象
         * 所以可以调用接口方法
         * 而此时调用接口方法又会转化为invoke方法
         * invoke方法中替换成被代理类对象
         */
        
        //举个栗子
        NikeClothFactory nike = new NikeClothFactory();
        //实现了ClothFactory接口,返回的是Object,这里强制转型,返回的是代理类对象
        ClothFactory pro = (ClothFactory)handler.blind(nike);
        //调用接口方法,转换为invoke方法,替换成nike对象
        pro.productCloth();
    }
}

你们看懂了嘛?反正我是懂了,接下来只需要练习,哈哈,我可真是个小机灵鬼

posted @ 2019-02-01 02:19  静心*尽力  阅读(235)  评论(0编辑  收藏  举报