`

第十四章 类型信息4.0

 
阅读更多
动态代理

Java的动态代理比代理的思想更向前迈进了一步,因为它可以动态地创建代理并动态地处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定相应的对策。下面是代码:

1.被代理类 的接口 Proxied
// 被代理类 需实现的 接口
public interface Proxied {
	void doSomething();
	void doSomethingElse(String str);
}

2.一个 Proxied接口 的实现类(被代理类)
public class ConcreteProxied implements Proxied {
	@Override
	public void doSomething() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			System.err.println("Error : InterruptedException");
		}
		System.out.println(this.getClass().getSimpleName()
				+ " >> doSomething .");
	}

	@Override
	public void doSomethingElse(String str) {
		try {
			Thread.sleep(150);
		} catch (InterruptedException e) {
			System.err.println("Error : InterruptedException");
		}
		System.out.println(this.getClass().getSimpleName()
				+ " >> doSomethingElse , argument = " + str + ".");
	}
}

3,TimingInvocationHandler 类,实现了 InvocationHandler 接口
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TimeingInvocationHandler implements InvocationHandler{
	//被代理的对象
	private Object proxied;
	public TimeingInvocationHandler(Object proxied){
		this.proxied = proxied;
	}
	
	// 参数  proxy 表示代理类的对象
	// 参数  method 表示被代理类 和 代理类 都实现的接口 的方法对象
	// 参数  args 表示方法 method 的参数数组
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println(method.getDeclaringClass().getName());
		long currentTimeMillis = System.currentTimeMillis();
		Object ret = method.invoke(proxied, args); //被代理对象的方法
		System.out.println(this.getClass().getSimpleName()+" >> wastes time : "
				+(System.currentTimeMillis() - currentTimeMillis)+"ms");
		return ret;
	}

}

4,测试类 Test
import java.lang.reflect.Proxy;

public class TestProxy {
	public static void main(String[] args) {
		Proxied proxied = new ConcreteProxied();
		proxied.doSomething();
		proxied.doSomethingElse("only a String");

		// 生成一个代理实例,这个代理实现了 Proxied 接口
		// 对这个代理(proxy)的方法的调用 会 重定向到 TimeingInvocationHandler 的 invoke 方法
		Proxied proxy = (Proxied) Proxy.newProxyInstance(Proxied.class
				.getClassLoader(), // 类加载器
				new Class[] { Proxied.class }, // 代理要实现的接口列表
				new TimeingInvocationHandler(proxied) // 调用处理器
				);
		proxy.doSomething();
		proxy.doSomethingElse("only a String");
	}

}

运行Test类,输出如下:

ConcreteProxied >> doSomething .
ConcreteProxied >> doSomethingElse , argument = only a String.
Proxied
ConcreteProxied >> doSomething .
TimeingInvocationHandler >> wastes time : 110ms
Proxied
ConcreteProxied >> doSomethingElse , argument = only a String.
TimeingInvocationHandler >> wastes time : 140ms

通过调用静态方法Proxy.newProxyInstance()可以创建动态代理,这个方法需要得到一个类加载器,一个你希望该代理实现的接口列表(不是类或抽象类),以及InvacationHandler接口的一个实现。动态代理可以将所有调用重定向到调用处理器,因此通常会向调用处理器的构造器传递给一个“实际”对象的引用,从而使得调用处理器在执行其中介任务时,可以将请求转发。

Invoke()方法中传递进来了代理对象,以防你需要区分请求的来源,但是在许多情况下,你并不关心这一点。然而,在invoke()内部,在代理上调用方法时需要格外当心,因为对接口的调用将被重定向为对代理的调用。

通常,你会行被代理的操作,然后使用Method.invoke()将请求转发给被代理对象,并传入必须的参数。这初看起来可能有些限制,就像你只能执行泛化操作一样,但是,你可以通过传递的参数,来过滤某些方法。
public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		if(method.getName().equals("interesting")) {
			System.out.println("interesting");
		}
}

Test类的:
proxy.doSomething();
proxy.interesting("bonobo");
proxy.doSomethingElse("only a String");


接口与类型信息
Method g = a.getClass().getDeClareMethod(methodName);
g.setAccessible(true);
g.invoke(a);

通过使用反射,仍旧可以到达并调用所有方法,甚至是private方法!
分享到:
评论

相关推荐

    ASP.NET4.0从入门到精通课件(18章)

    ### 第十三章至第十五章:安全性与性能优化 - **加密技术**:了解加密算法及其在保护敏感信息中的应用。 - **缓存策略**:分析不同类型的缓存机制,并讨论如何合理运用以提升网站性能。 - **异常处理**:强调异常...

    Pro Entity Framework 4.0

    #### 第十三章:使用实体框架进行数据绑定 **知识点概述:** 本章讲解了如何使用实体框架进行数据绑定,以提高UI的响应速度和用户体验。 **详细知识点:** - **数据绑定基础:** 如何使用实体框架中的数据填充...

    SDIO4.0协议英文版本

    14. **物理属性与机械扩展合并**:将第12章(物理属性)和第13章(机械扩展)合并为新的第13章(物理属性),并添加了 miniSDIO 描述。 15. **嵌入式 SDIO ATA 标准功能接口代码**:定义了与ATA接口标准兼容的...

    C# 4.0捷径教程 中文版 part2

    有人上传过,但是要5分,我重发一次方便分不多的朋友 讲解最新的C#4.0技术,入门必备 编辑推荐  好评如潮的C# 4.0实战图书  汲取.NET技术精髓的捷径  专章讲述习惯用法与...第14章 扩展方法 第15章 lambda表达式

    C# 4.0捷径教程 中文版 part1

    csdn里有前辈上传过,便是分有点高, 我重新上传一次,方便分不多的朋友 讲解最新的C#4.0技术,入门必备 编辑推荐  好评如潮的C# 4.0实战图书  汲取.NET技术精髓的捷径 ...第14章 扩展方法 第15章 lambda表达式

    C#4.0编程(第6版)

    ##### 第14章:数据库 - **数据库交互** - ADO.NET的使用。 - LINQ to SQL的应用。 - Entity Framework的数据访问。 ##### 第15章:程序集 - **程序集** - 程序集的加载与卸载。 - 程序集的签名与安全性。 ...

    Beginning WF 4.0翻译

    ##### 第十四章:事务 - **事务管理**: 探讨如何在工作流中使用事务来确保数据一致性。讨论事务的原子性和回滚机制。 ##### 第十五章:事务与持久化 - **事务持久化**: 结合事务和持久化的概念,阐述如何确保事务在...

    很详细的proe4.0课件

    - 第14章:有限元分析(FEA):学习如何进行结构、热、流体等类型的仿真分析,评估设计的强度和稳定性。 5. **进阶实践篇** - 第15章:综合案例:通过实际项目案例,综合运用前面所学知识,提高解决实际问题的...

    HTML4.0简明手册

    - 第十一章讲解了如何在网页中使用JavaScript进行动态交互。 - 使用`<script>`标签引入脚本代码。 通过以上知识点的总结,我们可以看出HTML4.0不仅提供了基本的文档结构定义,还支持丰富的多媒体元素和动态交互功能...

    Drools4.0官方使用手册中文

    第四章. 决策表 88 4.1. 在电子表格中的决策表 88 4.1.1. 何时使用决策表 88 4.1.2. 概述 89 4.1.3. 决策表如何工作 91 4.1.4. 关键字和语法 93 4.1.5. 基于决策表建立并集成电子表格 97 4.1.6. 在决策表中管理业务...

    北大青鸟C#课件ACCP4.0完整版(14)

    【北大青鸟C#课件ACCP4.0完整版(14)】是一套针对初学者和进阶者设计的全面C#编程教程。这个版本的课程是北大青鸟教育机构推出的第4.0版ACCP(Accelerated Career Computer Professional)认证课程的一部分,旨在帮助...

    CUDA Programming Guide 4.0

    - 第3章的序言被完全重写,以更好地介绍本章的主要内容。 - 删除了第3.2节序言中关于资源分配仅在主机线程上下文中有效的段落,因为该限制已经不再适用。 **5. 运行时初始化:** - 新增第3.2.1节,介绍运行时...

    Visual C#2010 开发权威指南源代码第14章

    1. **面向对象编程**:C#是一种强类型、面向对象的语言,第14章可能涉及类的设计、继承、封装、多态等概念,通过源代码展示如何创建和使用自定义对象。 2. **泛型**:C# 2010引入了泛型,使得代码可以更加通用,...

Global site tag (gtag.js) - Google Analytics