动态代理及JDK动态代理源码分析

1.为什么要动态代理
现在有这样一个需求:在聊天系统中,把每一个所说的话记录到日志文件里面,初学者可能是这样来设计


在speak方法中调用log方法,记录到数据库。这样设计有明显的不足:1、log方法不应该属于Person类中 2、如果改类库已经编译,我们就不能修改原有代码,在其方法内部增加代码。此时,有经验的开发者可能会想到代理模式。我们修改一下类图


我们将讲话给抽象出来,客户端使用接口声明,LogProxy与Person依赖,共同实现Speak接口,然后在LogPersonProxy中实现记录日志,这样就可以解决之前的问题。但是新问题又来了:我们必须为为委托类维护一个代理,不易管理而且增加了代码量。


2.JDK中的动态代理
JAVA的动态代理机制可以动态的创建代理并动态的处理代理方法调用,只要简单指定一组接口及为拖累对象,就能动态的获取代理类,JAVA已经给我们提供了强大的支持,其具体实现可以参照马士兵的动态代理视频。核心类是Proxy,负责创建所有代理类,并且创建的代理类都是其子类,而且这些子类继承所代理的一组接口,因此它就可以安全的转换成需要的类型,进行方法调用。InvocationHandler是调用处理器的接口,它自定义了一个invoke方法,用于机制处理在动态代理类上的方法调用,通常在该方法中实现对委托类的代理访问。相关类图如下



具体代理要实现InvocationHandler接口详细代码如下

public class LogProxy implements InvocationHandler {
 
 private Object object;
 public LogProxy(Object object) {
  super();
  this.object = object;
 }
 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  method.invoke(this.object, args);
  System.out.println("记录到数据库..");
  return null;
 }
 public void setObject(Object object) {
  this.object = object;
 }
 public Object getObject() {
  return object;
 }
}
public class PowerProxy implements InvocationHandler {
 private Object object;
 public PowerProxy(Object object) {
  super();
  this.object = object;
 }
 
 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  System.out.println("进行权限验证..是否是黑名单..");
  method.invoke(this.object, args);
  return null;
 }
 public void setObject(Object object) {
  this.object = object;
 }
 public Object getObject() {
  return object;
 }
}




我们可以在invoke方法中接到一下参数:Object proxy, Method method, Object[] args


其中,proxy是被代理的类,第二个参数表示被执行的委托方法,第三个参数表被执行的委托方法,我们在客户端测试一下,代码如下
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值