这个例子使用Java的动态代理技术演示了茶叶商家、代理商获取茶叶价格的例子,文章内容仅供加强理解之用,如有描述不妥之处,请参阅其他专业资料。
理解Java的动态代理
所谓代理,简单来说就是把一件事情交给别人去做,由别人替你代办。例如银行的代理人、娱乐圈的经纪人、商业中的经销商等等,都是一种代理的行为。
Java中的代理,是一样的道理,屏蔽了对原始对象实例的访问,由代理对象替代真实对象去完成。代理对象的类名称是$Proxy0
的形式,这个类是运行的时候动态生成的。
理解并掌握 Java的动态代理机制,对学习Spring框架有很大帮助。Spring框架中的AOP,本质上就是Java的动态代理。
演示例子
本文使用Java的动态代理技术,演示茶叶商家及其一级代理商、二级代理商获取产品价格的例子。
茶叶商家就是原始的商家,产品价格是原始销售价格。一级代理商在原始销售价格上,要获取5元的利润。二级代理商在原始销售价格上,要获取2元的利润。
代码如下:
商家
必须是一个接口类,因为代理者只关心代理什么方法,不关心具体如何代理。
package me.zebe.demo2;/*** 商家** @author Zebe*/public interface Seller {/*** 根据产品名称获取产品价格* @param productName 产品名称* @return 返回产品的价格*/int getProductPrice(String productName);}
茶叶商家
这是商家的具体实例,实现了 Seller 接口。
package me.zebe.demo2;/*** 茶叶商家** @author Zebe*/public class TeaSeller implements Seller {private final static String ZYQ = "竹叶青";private final static int ZYQ_PRICE = 300;@Overridepublic int getProductPrice(String productName) {if (ZYQ.equals(productName)) {System.out.println(String.format("茶叶商家报价,%s:%d 元/斤", productName, ZYQ_PRICE));return ZYQ_PRICE;} else {System.out.println(String.format("没有 %s 这项产品", productName));}return 0;}}
茶叶商家一级代理
package me.zebe.demo2;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/*** 茶叶商家一级代理** @author Zebe*/public class TeaSellerProxy1 {private static final String GET_PRODUCT_PRICE = "getProductPrice";/*** 要代理的商家*/private Seller seller = new TeaSeller();/*** 获取代理** @return 返回代理对象*/public Seller getProxy() {return (Seller) Proxy.newProxyInstance(TeaSellerProxy1.class.getClassLoader(),seller.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (GET_PRODUCT_PRICE.equals(method.getName())) {String productName = String.valueOf(args[0]);// 原始价格int originalPrice = Integer.parseInt(String.valueOf(method.invoke(seller, args)));// 代理价格int proxyPrice = originalPrice + 5;System.out.println(String.format("一级代理商报价,%s:%d 元/斤", productName, proxyPrice));return proxyPrice;}return null;}});}}
茶叶商家二级代理
package me.zebe.demo2;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/*** 茶叶商家二级代理** @author Zebe*/public class TeaSellerProxy2 {private static final String GET_PRODUCT_PRICE = "getProductPrice";/*** 要代理的商家*/private Seller seller = new TeaSeller();/*** 获取代理** @return 返回代理对象*/public Seller getProxy() {return (Seller) Proxy.newProxyInstance(TeaSellerProxy2.class.getClassLoader(),seller.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (GET_PRODUCT_PRICE.equals(method.getName())) {String productName = String.valueOf(args[0]);// 原始价格int originalPrice = Integer.parseInt(String.valueOf(method.invoke(seller, args)));// 代理价格int proxyPrice = originalPrice + 2;System.out.println(String.format("二级代理商报价,%s:%d 元/斤", productName, proxyPrice));return proxyPrice;}return null;}});}}
代理测试
package me.zebe.demo2;/*** 代理测试** @author Zebe*/public class ProxyTest {/*** 运行入口** @param args 运行参数*/public static void main(String[] args) {// 一级代理商获取竹叶青的价格Seller seller1 = new TeaSellerProxy1().getProxy();final String productName = "竹叶青";seller1.getProductPrice(productName);System.out.println("");// 二级代理商获取竹叶青的价格Seller seller2 = new TeaSellerProxy2().getProxy();seller2.getProductPrice(productName);}}
以上程序输出结果:
茶叶商家报价,竹叶青:300 元/斤一级代理商报价,竹叶青:305 元/斤茶叶商家报价,竹叶青:300 元/斤二级代理商报价,竹叶青:302 元/斤
以上为个人理解,参考了他人的学习资料,如有不正之处,敬请批评指正,感激不尽!
本文首发于个人独立博客,文章链接:http://www.zebe.me/java-dynamic-proxy