文档章节

Java的反射机制与动态代理(二):动态代理

伤了心的蜻蜓在唱歌
 伤了心的蜻蜓在唱歌
发布于 2017/03/28 16:37
字数 574
阅读 11
收藏 0

1. 为什么要使用动态代理?

在开发中我们会遇到这种情形,一个类中的方法随着业务的发展需要重新修改,而其他的方法还要使用该方法,遇到这种情形时该怎么做?举一个京东图书节促销的例子。假设所有的图书类(Book)都实现了IBook接口,在IBook接口中有一个方法getPrice,用于标识每一本书的价格,因为到了促销节会有很多的图书进行降价,但是在某个子程序中会调用原来的getPrice方法,因此,这个时候你不能贸然去修改原来的getPrice方法,避免其它模块不能正常工作。这个时候你可能会选择继承,创建一个新的类BookExtends继承自Book类,然后重新getPrice方法,由于getPrice方法没有提供额外的参数,因此在方法内你只能将促销价格固定,显然这种方式不可取,因为并不是每一本书的降价幅度都是一致的,为了解决这个问题,可以使用动态代理。

2. 如何使用动态代理?

还是以上面的例子,原始的业务处理过程如下程序所示:

package com.dd171290.proxy.book;

public interface IBook {
	float getPrice();
}
package com.dd171290.proxy.book;

public class ComputerBook implements IBook{

	public float getPrice() {
		return 100.0f;//计算机图书的原价为100元
	}
}

假设购买的图书有折扣,那么动态代理的方式:

package com.dd171290.proxy.book;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ComputerProxy {
	public static IBook getComputerProxy(final float discount) {
		Object object = Proxy.newProxyInstance(
				ComputerBook.class.getClassLoader(), //IBook实现类的类加载器
				new Class<?>[] { IBook.class },//实现类的接口
				new InvocationHandler() {//具体的处理类
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						//内部通过反射的机制来调用getPrice方法
						Object price = method.invoke(new ComputerBook(), args);
						return Float.parseFloat(price.toString()) - discount;
					}
				});
		return (IBook) object;
	}
}

测试效果:

package com.dd171290.proxy.book;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//原来的方法
		ComputerBook book=new ComputerBook();
		System.out.println(book.getPrice());
		
		//通过代理的形式
		IBook test=ComputerProxy.getComputerProxy(20.0f);
		System.out.println(test.getPrice());
	}

}

-----------result------------------------------
100.0
80.0

此为动态代理的简单用法,通过源码来分析,内部是使用反射(reflect)完成的,有兴趣的可以去研读源码的具体实现过程。

© 著作权归作者所有

伤了心的蜻蜓在唱歌
粉丝 0
博文 9
码字总数 9841
作品 0
开封
私信 提问
Java核心(六)反射和动态代理(JDK Proxy和Cglib)

反射和动态代理放有一定的相关性,但单纯的说动态代理是由反射机制实现的,其实是不够全面不准确的,动态代理是一种功能行为,而它的实现方法有很多。要怎么理解以上这句话,请看下文。 一、...

王磊的博客
2018/12/04
0
0
Java核心(六)反射和动态代理(JDK Proxy和Cglib)

反射和动态代理放有一定的相关性,但单纯的说动态代理是由反射机制实现的,其实是不够全面不准确的,动态代理是一种功能行为,而它的实现方法有很多。要怎么理解以上这句话,请看下文。 一、...

王磊的博客
2018/12/04
0
0
Java 动态代理及 RPC 框架介绍

原文出处:Frapples 所谓动态代理,指的是语言提供的一种语法,能够将对对象中不同方法的调用重定向到一个统一的处理函数中来。 python重写函数能够做到这一点,就连世界上最好的语言也提供称...

Frapples
2018/08/01
0
0
Java提高班(六)反射和动态代理(JDK Proxy和Cglib)

反射和动态代理放有一定的相关性,但单纯的说动态代理是由反射机制实现的,其实是不够全面不准确的,动态代理是一种功能行为,而它的实现方法有很多。要怎么理解以上这句话,请看下文。 一、...

王磊的博客
2018/12/11
0
0
设计模式3——Proxy设计模式

Proxy代理设计模式是一种控制对象访问的设计模式,类似于网络代理,网络代理机制如下图: Proxy代理设计模式机制如下: 代理模式UML图如下: 代理模式顺序图如下: 客户端程序通过代理程序来...

小米米儿小
2013/12/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用Apache Kudu和Impala实现存储分层

当为应用程序的数据选择一个存储系统时,我们通常会选择一个最适合我们业务场景的存储系统。对于快速更新和实时分析工作较多的场景,我们可能希望使用Apache Kudu,但是对于低成本的大规模可...

九州暮云
6分钟前
2
0
MySQL8.0 - 新特性 - 安全及权限相关改进

MySQL8.0里引入了不少关于权限的改动,从这些改动可以看出来,权限管理更加的规范和遍历了,这和我们之前为rds mysql增加了大量权限管理很类似,想来Oracle也是通过这些改动为其云业务服务的...

阿里云云栖社区
9分钟前
2
0
路由器的使用

第一步、连接无线路由器 把从房东家拉过来的网线,连接到路由器的WAN口;在准备一根网线,网线一端连接计算机,另一端连接路由器1、2、3、4口中的任意一个接口,如下所示。 从房东家拉网线上...

WinkJie
13分钟前
0
0
log4j:WARN No appenders could be found for logger

如提示,log4j没有配置日志记录的位置,需要配置log4j.properties,在src目录下新建log4j.properties, 将下面的内容写入文件 1.应用于控制台 log4j.appender.CONSOLE = org.apache.log4j.Co...

我叫小糖主
14分钟前
0
0
使用Eclipse内置的MAT插件分析dump文件时报错

下载下来一点dump文件很大,然后使用mat分析的时候mat本身报错 Out of Memory Error while Running the Memory Analyzer 这是因为eclipse配置的内存太小了导致的,网上查了下都是去改MemoryA...

V字仇杀
18分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部