(十五)代理

动态代理

Java中动态代理机制的引入使得代理模式的思想更加完善与进步,它允许动态的创建代理并支持对动态的对所代理的方法进行调用。Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类: 

Interface InvocationHandler

该接口中仅定义了一个方法Objectinvoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request()args为该方法的参数数组。这个抽象方法在代理类中动态实现。 

Proxy

该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容: 

Protected Proxy(InvocationHandler h)

构造函数,估计用于给内部的h赋值。 

Static Class getProxyClass (ClassLoader loader, Class[] interfaces)

获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。 

Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。 

 

所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。 下面我们通过动态代理来发送信息的例子!

先添加一个通过短信来发送消息的处理类:

//接口定义    

 public interface MessageHandler {    
   public void sendMessage(String msg);  
 }


public class SmsMessage implements MessageHandler {    
@Override    
public void sendMessage(String msg) {    
  // TODO Auto-generated method stub    
  System.out.println("SMS Message :" + msg+" sent !");    
}    
}    


//动态代理类    
import java.lang.reflect.InvocationHandler;    
import java.lang.reflect.Method;    
public class DynamicMessageProxy implements InvocationHandler {    
private static int count;    
private MessageHandler msgHandler;    
public DynamicMessageProxy(MessageHandler handler) {    
  msgHandler = handler;    
}    
@Override    
public Object invoke(Object proxy, Method method, Object[] args)    
throws Throwable {    
  // TODO Auto-generated method stub    
  System.out.println("++++++++=============+++++++++");    
  System.out.println("proxy:" + proxy.getClass());    
  System.out.println("method:" + method);    
  System.out.println("++++++++=============+++++++++");    
  if (args != null && args.length == 1 && checkMessage((String) args[0])) {    
    count++;    
    System.out.println("Message sent:" + count);    
    return method.invoke(msgHandler, args);    
  }    
  return null;    
}    
private boolean checkMessage(String msg) {    
  return msg != null && msg.length() > 10;    
}    
}    





//下面是调用    
import java.lang.reflect.Proxy;    
public class MainClass {    
private static void runProxy(MessageHandler handler) {    
  handler.sendMessage("message for test");    
}    
/**  
 * @param args  
 */    
public static void main(String[] args) {    
   MessageHandler handler = new SmsMessage();    
  handler.sendMessage("message for test");    
  MessageHandlerproxy = (MessageHandler) Proxy.newProxyInstance(MessageHandler.class    
  .getClassLoader(), new Class[] { MessageHandler.class },    
  new DynamicMessageProxy(handler));    
  proxy.sendMessage("message for test");     
  }    
}    

 

以上例子中,通过调用Proxy.newProxyInstance方法创建动态代理对象,该方法需要传入一个 类加载器、一组希望代理实现的接口列表、InvocationHandler 接口的一个具体实现。动态代理可以将所有调用重定向到调用处理器,通常我们会向该处理器传递一个时间对象的引用。invoke()方法中传递进来了代理对象,当你需要区分请求来源时这是非常有用的,例如你可以通过判断传入的方法名屏蔽掉某些方法的执行!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值