Java 创建对象方式:
● 用new语句创建对象
● 运用反射手段,调用java.lang.Class 或者 java.lang.reflect.Constructor 类的newInstance()实例方法
● 调用对象的clone()方法
● 运用序列化手段,调用java.io.ObjectInputStream 对象的 readObject()方法.
分别创建100万个javaBean ,性能如下:
//new : 46,47,47,62,47
//clone : 171,188,172,,157,172
//getClass().newInstance() : 140,141,141,,157,172
//Class.forName and newInstance : 1765,1781,1813,1797,1781
//Proxy.newProxyInstance : 2984
//Serializable : 60422
另外测试了Field 和 Method 执行效率:
//method : 1406
//feild : 1360 getField("")得到实例和父类的“公共”属性
//getDeclaredField() 得到实例的指定属性(Public,protected,dfault,pivate),不包括父类属性
//getFields()返回field数组, 得到实例 和 父类 的所有 “公共”属性
动态代理:
JDK:jdk1.7.0_02
CGLIB:和spring2.0.6 使用同样的cglib-nodep-2.1_3.jar
CPU:P8400 2.53GHz 2.53GHz
测试结果4:
Create JDK Proxy: 43 ms
Create CGLIB Proxy: 129 ms
Run JDK Proxy: 940 ms, 1,500,069 t/s
Run CGLIB Proxy: 299 ms, 4,715,937 t/s
CGLIB创建代理对象速度大概比JDK Proxy慢3倍,执行速度是JDK Proxy的3倍以上区别:
如果一个目标对象如果实现了接口Spring则会选择JDK动态代理策略动态的创建一个接口实现类(动态代理类)来代理目标对象,可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间在强制转换的时候会抛出java.lang.ClassCastException。而所以在默认情况下,如果目标对象没有实现任何接口,Spring会选择CGLIB代理, 其生成的动态代理对象是目标类的子类。spring 配置实用cglib动态代理
proxy-target-class 属性设为true 或 <aop:aspectj-autoproxy proxy-target-class="true"/>