`

java 反射机制(四)动态代理

阅读更多
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代
理类的能力

委托类和服务接口见静态代理中的IHelloService.java与HelloServiceImpl.java
这里给出动态代理类和测试类

动态代理类:
package reflection.proxy.dynamic;

import java.lang.reflect.*;

import reflection.proxy.Static.IHelloService;

public class HelloServiceProxyFactory { // 动态代理类
	/**
	 * 创建一个实现了HelloService 接口的动态代理类的实例 参数 helloService 引用被代理的HelloService 实例
	 */
	public static IHelloService getHelloServiceProxy(
			final IHelloService helloService) {

		/*
		 * InvocationHandler 接口为方法调用接口,它声明了负责调用任意一个方法的invoke()方法:
		 * 参数proxy指定动态代理类实例,参数method指定被调用的方法,参数args 指定
		 * 向被调用方法传递的参数,invoke()方法的返回值表示被调用方法的返回值。
		 */

		// 创建一个实现了InvocationHandler接口的匿名类的实例
		InvocationHandler handler = new InvocationHandler() {
			public Object invoke(Object proxy, Method method, Object args[])
					throws Exception {
				System.out.println("before calling " + method); // 预处理
				Object result = method.invoke(helloService, args);
				// 调用被代理的HelloService 实例的方法
				System.out.println("after calling " + method); // 事后处理
				return result;
			}
		};
		Class classType = IHelloService.class;

		// public static Class<?> getProxyClass(ClassLoader loader, Class<?>[]
		// interfaces)
		// 参数loader 指定动态代理类的类加载器,参数interfaces 指定动态代理类需要实现
		// 的所有接口。
		// )newProxyInstance()静态方法负责创建动态代理类的实例
		// 参数loader 指定动态代理类的类加载器,参数interfaces 指定动态代理类需要实现
		// 的所有接口,参数handler 指定与动态代理类关联的InvocationHandler 对象。
		return (IHelloService) Proxy.newProxyInstance(classType
				.getClassLoader(), new Class[] { classType }, handler);
	}// # getHelloServiceProxy()
}


测试类
package reflection.proxy.dynamic;

import reflection.proxy.Static.HelloServiceImpl;
import reflection.proxy.Static.IHelloService;

public class Client2 {
	public static void main(String args[]) {
		IHelloService helloService =  new HelloServiceImpl();
		IHelloService helloServiceProxy = HelloServiceProxyFactory
				.getHelloServiceProxy(helloService);
		System.out
				.println("动态代理类的名字为" + helloServiceProxy.getClass().getName());
		System.out.println(helloServiceProxy.echo("Hello"));
	}
}


执行结果:
动态代理类的名字为$Proxy0
before calling public abstract java.lang.String reflection.proxy.Static.IHelloService.echo(java.lang.String)
after calling public abstract java.lang.String reflection.proxy.Static.IHelloService.echo(java.lang.String)
echo:Hello
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics