Java之动态代理

来源:互联网 发布:数据库存储过程优点 编辑:程序博客网 时间:2024/05/24 05:03

    代理模式为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。典型的比如,业务对象专注于某些事情,但在所有业务方法之前之后必须记录日志。(当然,用Spring则另当别论)

    静态代理:编写代理类及代理方法。一个代理类只能为一个接口服务,所有的代理操作都要写,存在重复代码。

    动态代理:动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性 。

    下面就用一个王婆卖瓜的例子来演示动态代理基本使用。

1.SellWatermelon.java 业务接口

//卖瓜接口public interface SellWatermelon {public void sell();}


2.SellWatermelonImpl.java 业务实现类

//王婆卖瓜,实现sellWatermelon接口public class SellWatermelonImpl implements SellWatermelon {@Overridepublic void sell() {System.out.println("王婆卖瓜,自卖自夸!");}}


3.SellWatermelonProxy.java 代理类,在调用每个方法前后输出日志

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Arrays;//动态代理类public class SellWatermelonProxy {//代理对象private SellWatermelon target = null;public SellWatermelonProxy(SellWatermelon target) {this.target = target;}//返回动态代理类,即虚拟机动态生成public SellWatermelon getSellWatermelonProxy() {SellWatermelon proxy = null;//代理对象由哪一个类加载器加载ClassLoader loader = target.getClass().getClassLoader();//指定代理的接口,即代理哪些方法Class []interfaces = new Class[]{ SellWatermelon.class };//调用代理对象的方法时,即执行invoke方法InvocationHandler h = new InvocationHandler() {/* * proxy: 正在调用的代理对象 * method:正在调用的方法 * args: 调用的参数 */@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("动态代理调用" + method.getName() + "开始!");Object result = method.invoke(target, args);System.out.println("动态代理调用" + method.getName() + "结束!");return result;}};proxy = (SellWatermelon) Proxy.newProxyInstance(loader, interfaces, h);return proxy;}}

4.SellWatermelonTest.java 客户端,使用动态代理 。用JUnit测试

import static org.junit.Assert.*;import org.junit.Test;public class SellWatermelonTest {//不用代理调用@Testpublic void test() {SellWatermelon saler = new SellWatermelonImpl();saler.sell();}//使用动态代理调用@Testpublic void testProxy() {SellWatermelon saler = new SellWatermelonImpl();SellWatermelon proxy = new SellWatermelonProxy(saler).getSellWatermelonProxy();proxy.sell();}}




0 0
原创粉丝点击