黑马程序员__动态代理
来源:互联网 发布:windows系统优化软件 编辑:程序博客网 时间:2024/06/05 16:18
--------------- android培训、java培训、期待与您交流!---------------
今天重新看了一下动态代理和反射的视频。基本上搞懂了稍微测试和总结下。
动态代理:
1、JVM可以在运行期间动态的生成出类的字节码,这种动态生成的类往往被用作代理类,也就是动态代理。
2、JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
3、代理类Proxy的构造方法有参数,并且为InvocationHandler类型,所以在用反射返回Class类型的对象时,不能调用newInstance()为其创建一个实例。
4、CGLIB库可以动态的生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成代理类,那么可以使用CGLIB库。
二、用反射操作的基本步骤:
1、得到类的字节码。可以通过 对象.getClass(),类.class,Class.forName("类名")返回一个Class类型的对象。
2、Class类里面有各种各样的方法,得到类的各种成分,getMethod(),getConstructor()等等。但是注意:如果类里面的各种成分声明为private的话,要注意调用的方法有所不同。
3、得到各种成分之后就可以操作这样成分,但是操作类里面的“方法”这个成分就不一样,就要得到类的实例对象(静态方法除外),得到实例对象也有两种:
1)通过Class类的newInstance()但是如果类的构造方法有参数的话就不可以用。这个只能得到无参的构造方法的实例对象。
2)通过getConstructor(类型.class)来得到构造方法,返回的是Constructor类型的对象,然后用Constructor类型的对象去调用newInstance(参数)。
三、Proxy类:
Proxy类里面有一个方法:
newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h);
可以直接创建一个实例对象。下面是一些测试代码:用于通过Proxy类动态的创建代理类。
package net.proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;
public class ProxyTest {
publicstatic void main(String[] args) throws Exception,
NoSuchMethodException{
Classclazz = Proxy.getProxyClass(Collection.class.getClassLoader(),
Collection.class);
//clazz.newInstance();这个是不可以的。因为产生的动态类的构造方法是有参数的。
Constructorconstructor = clazz.getConstructor(InvocationHandler.class);
CollectioncollProxy = (Collection) constructor
.newInstance(newInvocationHandler() {
@Override
publicObject invoke(Object proxy, Method method,
Object[]args) throws Throwable {
returnnull;
}
});
//这个方法实际上是上面的两个步骤(得到Class类型的对象也就是代理类的字节码和创建实例)都给做了
CollectioncollProxy1 = (Collection) Proxy.newProxyInstance(
Collection.class.getClassLoader(),
newClass[] { Collection.class }, new InvocationHandler() {
ArrayListtarget = new ArrayList();
@Override
publicObject invoke(Object proxy, Method method,
Object[]args) throws Throwable {
ObjectretVal = method.invoke(target, args);// 这个是反射中的Method中调用目标对象方法的方法。args是为目标对象方法传递的参数。
returnretVal;
}
});
collProxy1.add("xxx");
//System.out.println(collProxy1);
//System.out.println(collProxy1.toString());
//System.out.println(collProxy1.size());
finalArrayList target = new ArrayList();
CollectioncollProxy2 = (Collection) Proxy.newProxyInstance(target
.getClass().getClassLoader(),new Class[] { Collection.class },
newInvocationHandler() {
@Override
/**
* @param proxy 为代理对象:collProxy2
* @param method 为代理对象要调用的方法
* @param args 为方法的参数
* 参照下面的collPrxy2.add("xxx");
* */
publicObject invoke(Object proxy, Method method,
Object[]args) throws Throwable {
ObjectretVal = method.invoke(target, args);// 这个是反射中的Method中调用目标对象方法的方法。args是为目标对象方法传递的参数。
returnretVal;
}
});
//代理的内部实现:调用add 方法,则去找invocationHandler
//里面的invoke方法-->调用method的invoke方法。这样返回值从handler中的invoke取。
//如果retVal为空的话,就不可以用collProxy2.size()因为他返回的是int
//,当它去handler去取的时候就返回空。。空==int ???所以出错了。
collProxy2.add("xxx");
//System.out.println(collProxy1);
System.out.println(collProxy2.toString());
System.out.println(collProxy2.size());
}
}
--------------- android培训、java培训、期待与您交流!---------------
- 黑马程序员__动态代理
- 黑马程序员__动态代理
- 黑马程序员__类加载器__代理
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员--动态代理
- 黑马程序员--动态代理
- 黑马程序员-动态代理
- 黑马程序员---------动态代理
- 黑马程序员-动态代理
- 黑马程序员-动态代理
- 黑马程序员-动态代理
- 黑马程序员 动态代理
- 黑马程序员-动态代理
- 黑马程序员------动态代理
- 黑马程序员 动态代理
- Oracle Flashback技术总结(恢复数据到某一刻)
- 微软:拭目我们如何打击Google
- 凡客被裁员工“三问陈年” 官方不予回应
- c++中new和delete的那些事2
- linux绑定多个ip(转载)
- 黑马程序员__动态代理
- 人人网8千万美元收购56.com 陈一舟的三场表演
- Google+负责人:开发者使用该平台只是时间问题
- 程序员在想什么?需要什么?
- 阅读程序代码的技巧与方法
- 【find】 字符串?树状数组~
- 第二章 嵌入式系统基本概念
- 微博营销的第一步测量问题
- 从乔布斯卸任看苹果未来三年 会否半途而废?