反射与动态代理

反射是动态语言的关键,动态代理正是通过反射实现

一.静态代理:

   静态代理是通过构建代理类对象,将被代理类对象以参数的形式传递给代理类对象,进而在代理类对象中调用被代理类的方法。

代码实现如下:

1.创建接口

2.定义被代理类实现接口

3.定义代理类,通过代理类的构造方法为其被代理类对象属性赋值,代理类的productCloth()方法实际调用的是被代理类对象的方法

4.建立main方法测试

package D19;

/**
 * @Author: wj
 * @Date: 2018/12/1 16:19
 * @Version 1.0
 *
 * 静态代理演示
 * 使用一个代理类将对象包装起来,然后用该代理对象取代原始对象,任何对原始对象的调用
 * 都要通过代理,代理对象决定是否以及何时将方法调用转到原始对象上
 */


/**
 *接口
 */
interface ClothFactory{
    public void productCloth();
}


/**
 *被代理类
 */
class NikeClothFactory implements ClothFactory{

    public void productCloth() {
        System.out.println("NIKE");
    }
}


/**
 * 代理类
 */
class ProxyFactory implements ClothFactory{
    ClothFactory cf ;

    /**创建代理类对象时,实际传入的是被代理类对象
     * @param cf(多态)
     */
    public ProxyFactory(ClothFactory cf){
        this.cf=cf;
    }


    public void productCloth() {
        cf.productCloth();
    }
}


public class TestStaticAgent {
    public static void main(String[] args) {
        NikeClothFactory nikeClothFactory = new NikeClothFactory();  //创建被代理类对象
        //代理类对象
        ProxyFactory proxyFactory = new ProxyFactory(nikeClothFactory);  //创建代理类对象
        //虽然执行的是代理类的productCloth();但实际调用的是被代理类的productCloth()方法
        proxyFactory.productCloth();
    }
}

5.输出:

二.动态代理

动态代理比静态代理更加自如,不必考虑代理类接受对象的类型,具有更加自如地灵活性,实现了动态代码

步骤与静态代理相同

1.定义接口

2.定义实现接口的被代理类

3.定义实现了InvocationHandler接口的代理类,定义blind方法接受被代理类对象(作用有两个1.为属性赋值,2返回实现了被代理类所实现接口的代理类对象),实现了invoke方法,该方法实际就是被带了类的方法

代码如下:

package D19;

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

/**
 * @Author: wj
 * @Date: 2018/12/2 13:38
 * @Version 1.0
 *
 * 动态代理的使用
 */



//接口
interface Subject{

    void action();
}


/**
 * 被代理类
 */
class RealSubject implements Subject{

    public void action() {
        System.out.println("被代理类执行");
    }
}


/**
 * 代理类
 */
class MyInvocationHandler implements InvocationHandler{
    Object object;//实现了接口的被代理类对象的声明(RealSubject)


    // 1.给被代理类的对象实例话
    //2.返回一个代理类的对象
    public Object blind(Object obj){
        this.object = obj;

        //三个参数被代理类对象的classLoader,被代理类实现的接口,实现了InvocationHandler接口的类对象
        return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
    }


    //当通过代理类的对象发起对被代理类方法的调用时,都会转为对invoke方法的调用,进而实现动态效果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //returnVal是被代理类方法的返回值
        Object returnVal =  method.invoke(object,args);


        System.out.println("invoke方法被调用");
        return returnVal;
    }
}


public class TestDynamicAgent {
    public static void main(String[] args) {
        //1.构造被代理类的对象
        RealSubject realSubject = new RealSubject();

        //2创建一个实现了InvocationHandle接口的对象
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler();

        //3.通过myInvocationHandle的blind方法 ,返回实现了被代理类所实现的接口的代理类对象
        Object obj =  myInvocationHandler.blind(realSubject);
        Subject sub = (Subject) obj;//sub就是i代理类的对象

        sub.action();//转到对代理类的inovke方法的调用





//        //测试动态代理
//        NikeClothFactory clothFactory = new NikeClothFactory();
//        Object demo = myInvocationHandler.blind(clothFactory);
//        ClothFactory clo = (ClothFactory) demo;
//        clo.productCloth();


    }
}

输出:

在main方法中还写了一个测试,具体的应用了动态代理。

猜你喜欢

转载自blog.csdn.net/weixin_38520617/article/details/84712561