WordPress打开速度不稳定,seo好学吗,wordpress 非插件代码高亮,做自己的网站需要多少钱2. 动态代理
2.1 好处#xff1a;
无侵入式的给方法增强功能
2.2 动态代理三要素#xff1a;
1#xff0c;真正干活的对象
2#xff0c;代理对象
3#xff0c;利用代理调用方法
切记一点#xff1a;代理可以增强或者拦截的方法都在接口中#xff0c;接口需要写在…2. 动态代理
2.1 好处
无侵入式的给方法增强功能
2.2 动态代理三要素
1真正干活的对象
2代理对象
3利用代理调用方法
切记一点代理可以增强或者拦截的方法都在接口中接口需要写在newProxyInstance的第二个参数里。
2.3 代码实现
public class Test {public static void main(String[] args) {/*需求外面的人想要大明星唱一首歌1. 获取代理的对象代理对象 ProxyUtil.createProxy(大明星的对象);2. 再调用代理的唱歌方法代理对象.唱歌的方法(只因你太美);*///1. 获取代理的对象BigStar bigStar new BigStar(鸡哥);Star proxy ProxyUtil.createProxy(bigStar);
//2. 调用唱歌的方法String result proxy.sing(只因你太美);System.out.println(result);}
}
/*
*
* 类的作用
* 创建一个代理
*
* */
public class ProxyUtil {/*** 方法的作用* 给一个明星的对象创建一个代理** 形参* 被代理的明星对象** 返回值* 给明星创建的代理**** 需求* 外面的人想要大明星唱一首歌* 1. 获取代理的对象* 代理对象 ProxyUtil.createProxy(大明星的对象);* 2. 再调用代理的唱歌方法* 代理对象.唱歌的方法(只因你太美);* */public static Star createProxy(BigStar bigStar){/* java.lang.reflect.Proxy类提供了为对象产生代理对象的方法
public static Object newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h)参数一用于指定用哪个类加载器去加载生成的代理类参数二指定接口这些接口用于指定生成的代理长什么也就是有哪些方法参数三用来指定生成的代理对象要干什么事情*/Star star (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),//参数一用于指定用哪个类加载器去加载生成的代理类new Class[]{Star.class},//参数二指定接口这些接口用于指定生成的代理长什么也就是有哪些方法//参数三用来指定生成的代理对象要干什么事情new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {/** 参数一代理的对象* 参数二要运行的方法 sing* 参数三调用sing方法时传递的实参* */if(sing.equals(method.getName())){System.out.println(准备话筒收钱);}else if(dance.equals(method.getName())){System.out.println(准备场地收钱);}//去找大明星开始唱歌或者跳舞//代码的表现形式调用大明星里面唱歌或者跳舞的方法return method.invoke(bigStar,args);}});return star;}
}
public interface Star {//我们可以把所有想要被代理的方法定义在接口当中//唱歌public abstract String sing(String name);//跳舞public abstract void dance();
}
public class BigStar implements Star {private String name;
public BigStar() {}
public BigStar(String name) {this.name name;}
//唱歌Overridepublic String sing(String name){System.out.println(this.name 正在唱 name);return 谢谢;}
//跳舞Overridepublic void dance(){System.out.println(this.name 正在跳舞);}
/*** 获取* return name*/public String getName() {return name;}
/*** 设置* param name*/public void setName(String name) {this.name name;}
public String toString() {return BigStar{name name };}
}
2.4 额外扩展
动态代理还可以拦截方法
比如
在这个故事中经济人作为代理如果别人让邀请大明星去唱歌打篮球经纪人就增强功能。
但是如果别人让大明星去扫厕所经纪人就要拦截不会去调用大明星的方法。
/*
* 类的作用
* 创建一个代理
* */
public class ProxyUtil {public static Star createProxy(BigStar bigStar){public static Object newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h)Star star (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),new Class[]{Star.class},new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if(cleanWC.equals(method.getName())){System.out.println(拦截不调用大明星的方法);return null;}//如果是其他方法正常执行return method.invoke(bigStar,args);}});return star;}
}
2.5 动态代理的练习
对add方法进行增强对remove方法进行拦截对其他方法不拦截也不增强
public class MyProxyDemo1 {public static void main(String[] args) {//动态代码可以增强也可以拦截//1.创建真正干活的人ArrayListString list new ArrayList();
//2.创建代理对象//参数一类加载器。当前类名.class.getClassLoader()// 找到是谁把当前的类加载到内存中了我再麻烦他帮我干一件事情把后面的代理类也加载到内存
//参数二是一个数组在数组里面写接口的字节码文件对象。// 如果写了List那么表示代理可以代理List接口里面所有的方法对这些方法可以增强或者拦截// 但是一定要写ArrayList真实实现的接口// 假设在第二个参数中写了MyInter接口那么是错误的。// 因为ArrayList并没有实现这个接口那么就无法对这个接口里面的方法进行增强或拦截//参数三用来创建代理对象的匿名内部类List proxyList (List) Proxy.newProxyInstance(//参数一类加载器MyProxyDemo1.class.getClassLoader(),//参数二是一个数组表示代理对象能代理的方法范围new Class[]{List.class},//参数三本质就是代理对象new InvocationHandler() {Override//invoke方法参数的意义//参数一表示代理对象一般不用了解//参数二就是方法名我们可以对方法名进行判断是增强还是拦截//参数三就是下面第三步调用方法时传递的参数。//举例1//list.add(阿玮好帅);//此时参数二就是add这个方法名//此时参数三 args[0] 就是 阿玮好帅//举例2//list.set(1, aaa);//此时参数二就是set这个方法名//此时参数三 args[0] 就是 1 args[1]aaapublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//对add方法做一个增强统计耗时时间if (method.getName().equals(add)) {long start System.currentTimeMillis();//调用集合的方法真正的添加数据method.invoke(list, args);long end System.currentTimeMillis();System.out.println(耗时时间 (end - start));//需要进行返回返回值要跟真正增强或者拦截的方法保持一致return true;}else if(method.getName().equals(remove) args[0] instanceof Integer){System.out.println(拦截了按照索引删除的方法);return null;}else if(method.getName().equals(remove)){System.out.println(拦截了按照对象删除的方法);return false;}else{//如果当前调用的是其他方法,我们既不增强也不拦截method.invoke(list,args);return null;}}});
//3.调用方法//如果调用者是list就好比绕过了第二步的代码直接添加元素//如果调用者是代理对象此时代理才能帮我们增强或者拦截
//每次调用方法的时候都不会直接操作集合//而是先调用代理里面的invoke在invoke方法中进行判断可以增强或者拦截proxyList.add(aaa);proxyList.add(bbb);proxyList.add(ccc);proxyList.add(ddd);
proxyList.remove(0);proxyList.remove(aaa);
//打印集合System.out.println(list);}
}