动态代理原理分析.md

package day15动态代理.动态代理练习;

import org.junit.Test;

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

public class test {
    @Test
    public void show(){
        liuyan ly=new liuyan();
        //类加载器,类加载器可以随便给,得到的只要是我们自定义的APP类加载器就可以
        //字节码文件进内存需要类加载器加载,我们写的类一般都在APP类加载器中,
        // sun公司写如String这些都是在根类加载器中Bootstrap 根类加载器;
        ClassLoader loder = ly.getClass().getClassLoader();
        //代理类和被代理类共同实现的接口,这里用.class类型。不能直接class[] arr={star.class},这样的话就写死了,因为代理类可能有多个接口
        //所以用class中的getinterfaces 获取这个class文件的所有接口放入class[]数组
        Class[] interfaces = ly.getClass().getInterfaces();
        //Proxy代理类,newPrxyInstance获取一个代理类的实例。
        //Proxy.newProxyInstance()相当于一个代理类对象,相当于锁哥,然后强转为Star类型,因为返回值是Object,我们想要操纵接口中的方法
        Star s = (Star) Proxy.newProxyInstance(loder, interfaces, new InvocationHandler() {
            //InvocationHandler 是方法处理器,用来处理方法的,每次代理类对象也就是s每次操纵方法,都会执行一次invoke方法
            //method 是interfaces数组中的所有方法,当s调用哪个,他就代表哪个方法;
            //Object proxy  代理类对象,随调用我我就代表谁,也就是代表s
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //不一定非要通过方法获取,只要能证明他是哪个方法就行,也可以用长度等等
                String name = method.getName();
                if ("sing".equals(name)){
                    //如果进来,那么代表进来的是sing方法
                    //args代表的参数,他是数组类型,因为sing有一个参数,所以他的参数是数组中的第一个
                    //因为返回值是object类型,所以我们要强转成我们需要的类型
                    double arg = (double) args[0];
                    if (arg<20000){
                        System.out.println("一边玩泥巴去!");
                        return null;
                    }
                    System.out.println("我提取了"+arg*0.2+"元");
                    //调用method的invoke方法执行方法,return如果有返回返回值,没有就会返回null
                    return method.invoke(ly,arg*0.8);
                }
                if ("liveshow".equals(name)){
                    double arg = (double) args[0];
                    if (arg<30000){
                        System.out.println("一边玩泥巴去!");
                        return null;
                    }
                    System.out.println("我提取了"+arg*0.2+"元");
                    //调用method的invoke方法执行方法,return如果有返回返回值,没有就会返回null
                    return method.invoke(ly,arg*0.8);
                }
                //剩下的只有一个sleep方法了所以不需要判断了,以为sleep没有参数所以不用给,invoke的参数是可变参数,可以给可以不给
                return method.invoke(ly);
            }
        });
        //代理类调用方法,每次都调用方法都执行InvocationHandler()处理器的invoke方法
        s.liveshow(20000);
        s.sing(50000);
        s.sleep();

    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42485823/article/details/82900580