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();
}
}
动态代理原理分析.md
猜你喜欢
转载自blog.csdn.net/weixin_42485823/article/details/82900580
今日推荐
周排行