----------------------android培训、java培训、java学习型技术博客、期待与您交流!----------------------
动态代理技术:
要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中
下面的代码演示如何产生一个动态类:
public class ProxyTest {
public static void main(String[] args) throws Exception {
//创建动态类Proxy.getProxyClass(Classloader, class);
Class clazzProxy = Proxy.getProxyClass(Collection.class
.getClassLoader(), Collection.class);
//获得动态类的构造函数
Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class);
//编写一个InvocationHandler的实现类
class MyInvocationHander1 implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
//实例化一个Collection对象
Collection proxy1 = (Collection) constructor.newInstance(new MyInvocationHander1());
System.out.println("proxy1 : " + proxy1);
/*
* 产生动态代理类的第二种方法
*/
Collection proxy2 = (Collection) constructor.newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
System.out.println("proxy2 : " + proxy2);
}
}
以下代码演示如何使动态生成的类成为目标类的代理类
import java.lang.reflect.Method;
public interface Advice {
void beforeMethod(Method method);
void afterMethod(Method method);
}
import java.lang.reflect.Method;
public class MyAdvice implements Advice {
long startTime = 0;
long endTime;
@Override
public void afterMethod(Method method) {
System.out.println("程序结束了");
endTime = System.currentTimeMillis();
System.out.println(method.getName() + " 运行了" + (endTime - startTime));
}
@Override
public void beforeMethod(Method method) {
System.out.println("程序开始了");
startTime = System.currentTimeMillis();
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class CopyOfProxyTest {
public static void main(String[] args) throws Exception {
final ArrayList target = new ArrayList();
//获得一个Collection的代理类
Collection proxy = (Collection) getProxy(target, new MyAdvice());
//proxy对应invoke方法中的proxy参数
//add对应invoke方法中的method参数
//"aaa"对应invoke方法中的args参数
proxy.add("aaa");
proxy.add("bbb");
proxy.add("ccc");
System.out.println(proxy.size());
}
//获得代理
private static Object getProxy(final Object target, final Advice advice) {
Object proxy = Proxy.newProxyInstance(
//目标类的类加载器
target.getClass().getClassLoader(),
//与目标实现相同的接口
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
advice.beforeMethod(method); //在调用目标类之前执行的方法
Object retVal = method.invoke(target, args);
advice.afterMethod(method); //在调用目标类之后执行的方法
return retVal;
}
});
return proxy;
}
}
----------------------android培训、java培训、java学习型技术博客、期待与您交流!----------------------
详情请查看:http://edu.csdn.net/heima
分享到:
相关推荐
黑马程序员-java32期培训视频(基础+就业)黑马程序员-java32期培训视频(基础+就业)
day01_Object类、常用API day02_Collection、泛型 day03_List、Set、数据结构、Collections day04_Map,斗地主案例 day05_异常,线程 day06_线程、同步 day07_等待与唤醒案例、线程池、Lambda...Java基础小节练习题答案
黑马程序员 - Java基础教学 - 05 - 面向对象(1).doc
黑马程序员 - Java基础教学 - 04 - 数组、进制转换、二维数组
黑马程序员 - Java基础教学 - 08 - 面向对象(4)-多态.doc
黑马程序员 - Java基础教学 - 03 - 变量的作用域、for循环、break、continue、内存结构
黑马程序员 - 毕向东 - Java基础教学 - 第02天 个人观看视频总结文档
黑马程序员 - 毕向东 - Java基础教学 - 第01天 个人观看视频总结文档
黑马程序员 - Java基础教学 - 06 - 面向对象(2) - 关于静态static的那些事.doc
黑马程序员-SpringCloud-学习笔记-03-Eureka注册中心
NULL 博文链接:https://huangminwen.iteye.com/blog/1157983
黑马程序员-SpringCloud-学习笔记01-认识微服务
黑马QT讲义,适合QT入门,使用,教程很比较基础,新手可以看看,另外视频链接在哔哩哔哩中。
黑马程序员-SpringCloud-学习笔记-02-微服务拆分及远程调用
黑马程序员--毕向东全套Java视屏,讲解的相当全面,各位如果需要,尽快下载哦! 另外如果视频链接存在打不开的问题,请留言,必定及时更新链接。
月薪过万的入门必知知识,黑马程序员入学Java精华总结
黑马程序员-梅兰商城项目实战,包含图片素材和编写源码。
C++黑马程序员-演讲比赛流程管理系统记录
Java 黑马程序员入学Java知识(精华总结)
NULL 博文链接:https://840198532-qq-com.iteye.com/blog/1490901