java学习之路----静态代理---动态代理-----AOP的前奏(AOP也是动态代理)(一)

2014-11-24 08:09:46 · 作者: · 浏览: 4
什么叫代理? 什么是静态代理?什么是动态代理?
我觉得用代码可以解释这一切。。
直接看代码:

1.现在我们来建立一个java项目,叫Proxy,建立一个类,叫Tank,继续建立一个接口,叫Moveable,我们用Tank 来实现Moveable(意思就是坦克实现移动)
public interface Moveable {
void move();//移动接口
}
public class Tank implements Moveable {
@Override
public void move() {
System. out.println( "Tank moving....");//简单的输出一句话就代表移动了
}
}

我们再建立一个测试的服务端 叫Client类
public class Client { public static void main(String[] args) { Moveable m=new Tank(); m.move(); }
}
运行一下,结果:
Tank moving....

证明我们第一步成功了
2.现在假设我们把这段代码提交到了一个地方,我们不可以去修改 源码了,我们又想添加新的功能怎么办?
一般有两种方法:继承和聚合
来先看下继承:
我们来建立一个Tank2类来继承Tank,并且增加一个新的功能,叫计时的功能,就是方法开始运行就记下当前时间,结束的时候也记下结束的时间,然后相减,就得到了运行时间
public class Tank2 extends Tank{
@Override public void move() { long start=System. currentTimeMillis(); super.move(); long end=System. currentTimeMillis(); System. out.println((end-start)); }
}
我们修改测试类来看一下:
public class Client { public static void main(String[] args) { Moveable m= new Tank2(); m.move();
}
} 结果: Tank moving.... 0
结果是0ms,这样看不出效果,那我们再加一个线程的睡眠

修改代码: public class Tank implements Moveable {
@Override public void move() { System. out.println( "Tank moving...."); try { Thread. sleep( new Random().nextInt(10000)); } catch (InterruptedException e) { e.printStackTrace(); } }
}
运行测试类:
Tank moving.... 2995
这样就看出了运行时间

这上面的功能就是代理功能

我们在来看聚合

我们要聚合,就要先建立一个TankTimeProxy类,并且实现moveable接口,这个就是来计算tank移动方法运行的时间
看代码: public class TankTimeProxy implements Moveable{ public TankTimeProxy(Tank t) { this.t = t; } Tank t;//这里给一个tank对象进来,这就聚合(在一个类中引入另一个类的对象) @Override public void move() { long start=System. currentTimeMillis(); t.move(); long end=System. currentTimeMillis(); System. out.println((end-start)); } } 修改测试类:
public class Client { public static void main(String[] args) { Tank m= new Tank(); TankTimeProxy time= new TankTimeProxy(m); time.move();
}
}
结果: Tank moving.... 923
3.这两个哪个好喃?
如果现在我们还要增加一个日志的功能,如果是继承,我们还要写一个类来继承Tank2,但是用户又说,我要求先日志,在计算时间,那么是不是又要写个类来实现movaable接口,来修改喃,这样就会造成类的无限增长,这显然是不合理的,所以我们要用聚合。。聚合,无论你增加多少功能,我都可以互相交换

下面来看下聚合的代码:
我们先增加一个加 TankLogProxy的类,同样也实现了moveable接口
public class TankLogProxy implements Moveable { public TankLogProxy(Tank t) { this.t = t; }
Tank t; @Override public void move() { System. out.println("Tank start" ); t.move(); System. out.println("Tank end" ); }
}
如果我们要想互相交换,那我们还需要修改一下代码:
public class TankLogProxy implements Moveable { public TankLogProxy(Moveable t) { this.t = t; }
Moveable t; @Override public void move() { System. out.println("Tank start" ); t.move(); System. out.println("Tank end" ); }
}
public class TankTimeProxy implements Moveable { public TankTimeProxy( Moveable t) { this.t = t; } Moveable t ; @Override public void move() { long start=System. currentTimeMillis(); t.move(); long end=System. currentTimeMillis(); System. out.println((end-start)); } }
我们都把我们要传进来的对象变成Moveable的对象,因为我们都是实现了moveable接口
我们来写测试类 先日志,在时间 public class Client { public static void main(String[] args) { Tank t= new Tank(); TankLogProxy log= new TankLogProxy(t);//这里传的是tank的对象。tank也是moveable的对象 TankTimeProxy time= new TankTimeProxy(log); Moveable m=time; m.move(); }
} 结果: Tank start Tank moving.... Tank end 3639

满足我们的要求,如果现在我们要先时间,再日志,我们只需要修改一下测试类就oK
看代码: