`

JDK8 动态代理,及性能测试

 
阅读更多

先说结论:

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);
	}
}

  

 

 

 

分享到:
评论

相关推荐

    JDK动态代理源码

    在Java编程领域,JDK动态代理是一个非常重要的概念,它允许我们在运行时动态地创建一个实现了特定接口的代理对象,以此来拦截并扩展原有对象的行为。动态代理在很多场景下都有应用,比如AOP(面向切面编程)、事件...

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理)

    Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解对象获取、日志、用户鉴权、全局性异常处理、性能监控等领域。...

    JDK内置动态代理例子

    在Java开发中,JDK内置的动态代理机制是一种强大的工具,它允许我们在运行时创建具有额外功能的对象。这个“JDK内置动态代理例子”旨在演示如何利用Java的反射API和`java.lang.reflect.Proxy`类来实现类似拦截器的...

    springboot中的 动态代理的选择测试代码

    Spring AOP提供了两种动态代理方式:JDK代理和CGLIB代理。选择哪种代理方式取决于目标对象是否实现了接口。 1. JDK代理:如果目标对象实现了至少一个接口,Spring AOP会使用JDK的动态代理机制。在这种情况下,...

    JDK动态代理和Cglib动态代理实例源码

    - **使用场景**:如果目标类已经实现了接口,且不关心性能,优先选择JDK代理;否则,Cglib是更好的选择。 在`DynamicProxyTest`源码中,我们可以看到这两个代理方式的实现。测试代码通常会包含以下部分: - 创建...

    jdk动态代理

    在JDK中,动态代理是一种强大的功能,它允许我们在运行时创建代理对象,这些代理对象可以作为其他对象的代理,执行额外的操作或者扩展目标对象的功能。动态代理在很多场景下都非常有用,例如AOP(面向切面编程)、...

    从JDK动态代理到spring AOP

    本篇将详细探讨JDK动态代理和Spring AOP,以及它们在实际应用中的作用。 首先,JDK动态代理是Java提供的一种在运行时创建代理对象的技术。它允许我们在不修改原有类的基础上,为已有接口添加额外的功能。动态代理的...

    输出JDK和CGLib动态代理产生的class文件.zip

    1. JDK代理项目: - src/main/java:包含目标接口和其实现类 - target/classes:编译后的class文件,包括目标接口和实现类的class文件,以及由Proxy生成的代理类class文件 - 测试代码:展示如何使用Proxy创建代理...

    spring5.0和4.2.0 jdk8和jdk7 对应的版本

    但是,如果项目或计划升级到JDK 8,那么选择Spring 5.0将带来更多的新特性和性能提升。需要注意的是,尽管Spring 5.0理论上也可以在JDK 7下运行,但官方建议使用JDK 8,因为这样可以充分利用新版本的所有功能和优化...

    jdk6,8,11.rar

    它引入了许多改进和新特性,例如增强的Swing组件、新的I/O API、XML处理API的改进以及对Java动态代理的支持。JDK 6还增强了性能和内存管理,为开发者提供了更好的开发体验。对于那些需要兼容旧系统或旧代码库的项目...

    jdk-8u301-windows-x64.exe

    8. **Java动态代理(Dynamic Proxies)**: JDK 8提供了更强大的动态代理机制,允许在运行时创建接口的实现类,这对于AOP(面向切面编程)和测试框架非常有用。 9. **Nashorn JavaScript引擎**: JDK 8引入了Nashorn ...

    JDK动态代理

    JDK动态代理是Java语言提供的一种机制,它允许在运行时创建代理类,这些代理类可以拦截并增强原目标类的方法调用。这种技术在处理需要动态监控或扩展功能的场景下非常有用,例如AOP(面向切面编程)和事件处理等。...

    【IT十八掌徐培成】Java基础第25天-05.jdk动态代理.zip

    JDK动态代理的适用场景通常包括AOP(面向切面编程)框架、测试工具(如Mockito)、事件监听系统等。虽然JDK动态代理对于单接口实现的类非常方便,但如果目标类需要实现多个接口,或者是一个非接口类型的类,那么可能...

    Java动态代理(JDK和cglib)

    ### Java动态代理(JDK和cglib) #### 一、代理模式概述 代理模式是一种结构型设计模式,其中代理类含有一个对真实主题对象的引用,这样代理对象就可以执行一些预备或清理工作,并将真正的调用传递给真实主题对象...

    JDK帮助文档(jdk6,8,9,10,11)

    - **动态代理**:支持创建接口的动态实现类,便于实现AOP(面向切面编程)或其他动态行为。 2. **JDK 8**: - **Lambda表达式**:这是JDK 8最重要的特性,引入了函数式编程的概念,简化了多线程编程和处理集合。 ...

    动态代理实现文件.....

    但是,它的性能通常比JDK动态代理稍差,因为涉及到字节码的生成和类加载。 在实际应用中,例如Spring AOP(面向切面编程)框架就大量使用了动态代理技术,它可以根据配置自动为指定的对象生成代理,实现事务管理、...

    JDK1.8和JDK1.6API帮助文档

    3. **动态代理**:Java.lang.reflect.Proxy支持动态创建代理对象,方便实现回调和AOP(面向切面编程)。 4. **增强的数据库连接(JDBC)**:JDBC API增加了对存储过程的支持,提升了SQL查询的执行效率。 5. **XML...

    静态代理和动态代理Demo

    `Test.java`文件很可能是测试类,用于验证静态代理和动态代理的正确性。 静态代理和动态代理之间的主要区别在于灵活性。静态代理在编写时就需要知道真实对象的类型,而动态代理可以在运行时动态地创建代理对象,...

Global site tag (gtag.js) - Google Analytics