先说结论:
1,动态代理,继承Proxy,类实现接口。但需要反射。动态代理类,会被缓存。但反射仍慢。
2,100M次性能结果:
testDynamicProxyPerformance=73277 //先newInstance(),再方法的反射调用。
testDynamicProxyFilePerformance=1639 //没有newInstance(),只有方法的反射调用。
testStaticProxyPerformance=38
过程:
1,接口。
package time.river.proxy; public interface ITarget{ public void doA(int age); public void doB(String name, int age); public int getAge(); public void setAge(int age); }
2,目标类
package time.river.proxy; public class MyTarget implements ITarget { private int age; @Override public void doA(int age) { System.out.println("doA.....,age=" + age); } @Override public void doB(String name, int age) { System.out.println("doB.....,name=" + name + ",age=" + age); } @Override public int getAge() { return age; } @Override public void setAge(int age) { this.age = age; } }
3,Handler
package time.river.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyHandler implements InvocationHandler { private Object targetObj; public MyHandler(Object targetObj) { this.targetObj = targetObj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // System.out.println("哥是代理------------------------------------"); return method.invoke(targetObj, args); } }
4, 测试类
package time.river.proxy; import java.io.FileOutputStream; import java.lang.reflect.Proxy; import sun.misc.ProxyGenerator; public class Test { public static void main(String args[]) throws Exception{ // testDynamicProxy(); // createProxyClassFile(); // testProxyFile(); testDynamicProxyPerformance(); testDynamicProxyFilePerformance(); testStaticProxyPerformance(); } private static void testDynamicProxy() throws Exception{ MyTarget target = new MyTarget(); ITarget proxy = (ITarget) Proxy.newProxyInstance(ITarget.class.getClassLoader(), new Class[] { ITarget.class }, new MyHandler(target)); // proxy.doA(20); // proxy.doB("wnj", 20); proxy.setAge(20); } /** * 生成的动态代理文件。使用jad反编译。 */ private static void createProxyClassFile() throws Exception{ String name = "DynamicProxy"; //生成的动态代理文件。 //Proxy内部方法:ProxyGenerator.generateProxyClass。 byte[] data = ProxyGenerator.generateProxyClass(name, new Class[] { ITarget.class }); FileOutputStream out = new FileOutputStream(name + ".class"); out.write(data); out.close(); } public static void testProxyFile(){ MyTarget target = new MyTarget(); MyHandler handler = new MyHandler(target); DynamicProxy proxy = new DynamicProxy(handler); // proxy.doA(20); // proxy.doB("wnj", 20); proxy.setAge(20); } private static int cnt = 1000 * 1000 * 100; private static void testDynamicProxyPerformance() throws Exception{ long s = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { testDynamicProxy(); } long e = System.currentTimeMillis(); System.out.println("testDynamicProxyPerformance="+(e-s)); } private static void testDynamicProxyFilePerformance() throws Exception{ long s = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { testProxyFile(); } long e = System.currentTimeMillis(); System.out.println("testDynamicProxyFilePerformance="+(e-s)); } private static void testStaticProxyPerformance() throws Exception{ long s = System.currentTimeMillis(); for (int i = 0; i < cnt; i++) { testStaticProxy(); } long e = System.currentTimeMillis(); System.out.println("testStaticProxyPerformance="+(e-s)); } public static void testStaticProxy(){ MyTarget target = new MyTarget(); StaticProxy proxy = new StaticProxy(target); // proxy.doA(20); // proxy.doB("wnj", 20); proxy.setAge(20); } }
5,动态代理类。保存到class文件,再用jad反编译。
package time.river.proxy; import java.lang.reflect.*; import time.river.proxy.ITarget; /** * Test类createProxyClassFile()方法,生成的class文件。然后用jad反编译,再修改语法错误。 */ public final class DynamicProxy extends Proxy implements ITarget { public DynamicProxy(InvocationHandler invocationhandler) { super(invocationhandler); } public final void setAge(int i) { try { super.h.invoke(this, m6, new Object[] { Integer.valueOf(i) }); return; } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final boolean equals(Object obj) { try { return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })).booleanValue(); } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return false; } public final void doA(int i) { try { super.h.invoke(this, m3, new Object[] { Integer.valueOf(i) }); return; } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final int getAge() { try { return ((Integer) super.h.invoke(this, m5, null)).intValue(); } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return 0; } public final void doB(String s, int i) { try { super.h.invoke(this, m4, new Object[] { s, Integer.valueOf(i) }); return; } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return 0; } public final String toString() { try { return (String) super.h.invoke(this, m2, null); } catch (Error _ex) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return ""; } private static Method m6; private static Method m1; private static Method m3; private static Method m5; private static Method m4; private static Method m0; private static Method m2; static { try { m6 = Class.forName("time.river.proxy.ITarget").getMethod("setAge", new Class[] { Integer.TYPE }); m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m3 = Class.forName("time.river.proxy.ITarget").getMethod("doA", new Class[] { Integer.TYPE }); m5 = Class.forName("time.river.proxy.ITarget").getMethod("getAge", new Class[0]); m4 = Class.forName("time.river.proxy.ITarget").getMethod("doB", new Class[] { Class.forName("java.lang.String"), Integer.TYPE }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); } catch (NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch (ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } }
6,静态代理类
package time.river.proxy; public class StaticProxy implements ITarget{ private ITarget target; public StaticProxy(ITarget target) { super(); this.target = target; } @Override public void doA(int age) { } @Override public void doB(String name, int age) { } @Override public int getAge() { return 0; } @Override public void setAge(int age) { target.setAge(age); } }
相关推荐
在Java编程领域,JDK动态代理是一个非常重要的概念,它允许我们在运行时动态地创建一个实现了特定接口的代理对象,以此来拦截并扩展原有对象的行为。动态代理在很多场景下都有应用,比如AOP(面向切面编程)、事件...
Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解对象获取、日志、用户鉴权、全局性异常处理、性能监控等领域。...
在Java开发中,JDK内置的动态代理机制是一种强大的工具,它允许我们在运行时创建具有额外功能的对象。这个“JDK内置动态代理例子”旨在演示如何利用Java的反射API和`java.lang.reflect.Proxy`类来实现类似拦截器的...
Spring AOP提供了两种动态代理方式:JDK代理和CGLIB代理。选择哪种代理方式取决于目标对象是否实现了接口。 1. JDK代理:如果目标对象实现了至少一个接口,Spring AOP会使用JDK的动态代理机制。在这种情况下,...
- **使用场景**:如果目标类已经实现了接口,且不关心性能,优先选择JDK代理;否则,Cglib是更好的选择。 在`DynamicProxyTest`源码中,我们可以看到这两个代理方式的实现。测试代码通常会包含以下部分: - 创建...
在JDK中,动态代理是一种强大的功能,它允许我们在运行时创建代理对象,这些代理对象可以作为其他对象的代理,执行额外的操作或者扩展目标对象的功能。动态代理在很多场景下都非常有用,例如AOP(面向切面编程)、...
本篇将详细探讨JDK动态代理和Spring AOP,以及它们在实际应用中的作用。 首先,JDK动态代理是Java提供的一种在运行时创建代理对象的技术。它允许我们在不修改原有类的基础上,为已有接口添加额外的功能。动态代理的...
1. JDK代理项目: - src/main/java:包含目标接口和其实现类 - target/classes:编译后的class文件,包括目标接口和实现类的class文件,以及由Proxy生成的代理类class文件 - 测试代码:展示如何使用Proxy创建代理...
但是,如果项目或计划升级到JDK 8,那么选择Spring 5.0将带来更多的新特性和性能提升。需要注意的是,尽管Spring 5.0理论上也可以在JDK 7下运行,但官方建议使用JDK 8,因为这样可以充分利用新版本的所有功能和优化...
它引入了许多改进和新特性,例如增强的Swing组件、新的I/O API、XML处理API的改进以及对Java动态代理的支持。JDK 6还增强了性能和内存管理,为开发者提供了更好的开发体验。对于那些需要兼容旧系统或旧代码库的项目...
8. **Java动态代理(Dynamic Proxies)**: JDK 8提供了更强大的动态代理机制,允许在运行时创建接口的实现类,这对于AOP(面向切面编程)和测试框架非常有用。 9. **Nashorn JavaScript引擎**: JDK 8引入了Nashorn ...
JDK动态代理是Java语言提供的一种机制,它允许在运行时创建代理类,这些代理类可以拦截并增强原目标类的方法调用。这种技术在处理需要动态监控或扩展功能的场景下非常有用,例如AOP(面向切面编程)和事件处理等。...
JDK动态代理的适用场景通常包括AOP(面向切面编程)框架、测试工具(如Mockito)、事件监听系统等。虽然JDK动态代理对于单接口实现的类非常方便,但如果目标类需要实现多个接口,或者是一个非接口类型的类,那么可能...
### Java动态代理(JDK和cglib) #### 一、代理模式概述 代理模式是一种结构型设计模式,其中代理类含有一个对真实主题对象的引用,这样代理对象就可以执行一些预备或清理工作,并将真正的调用传递给真实主题对象...
- **动态代理**:支持创建接口的动态实现类,便于实现AOP(面向切面编程)或其他动态行为。 2. **JDK 8**: - **Lambda表达式**:这是JDK 8最重要的特性,引入了函数式编程的概念,简化了多线程编程和处理集合。 ...
但是,它的性能通常比JDK动态代理稍差,因为涉及到字节码的生成和类加载。 在实际应用中,例如Spring AOP(面向切面编程)框架就大量使用了动态代理技术,它可以根据配置自动为指定的对象生成代理,实现事务管理、...
3. **动态代理**:Java.lang.reflect.Proxy支持动态创建代理对象,方便实现回调和AOP(面向切面编程)。 4. **增强的数据库连接(JDBC)**:JDBC API增加了对存储过程的支持,提升了SQL查询的执行效率。 5. **XML...
`Test.java`文件很可能是测试类,用于验证静态代理和动态代理的正确性。 静态代理和动态代理之间的主要区别在于灵活性。静态代理在编写时就需要知道真实对象的类型,而动态代理可以在运行时动态地创建代理对象,...