记得刚接触代理,是在大话设计模式,最近在技术总结和学些java的过程又接触到静态代理和动态代理,尤其是动态代理,在学习AOP时,用到了动态代理,下面我用一些例子来对静态代理和动态代理做个总结。
其实用了代理之后最大的好处就是隐藏了真实类(委托类),这样更加安全,而静态代理和动态代理最大的区别就是,静态代理的代理类是程序员自己写的,在程序运行之前就已经存在的,而动态代理则是在程序运行时动态生成的,而且因为动态代理更加灵活,也常被应用。
首先先用一张UML图来理解一下代理是怎么回事?
其实静态代理就是在代理类中放入对为委托类的引用,然后将委托类作为代理类的构造函数的参数,这样在客户端调用时就不会看到委托类了。
1、公共接口,委托类和代理类都来集成它,这样代理类就具有了委托类所有的方法和属性
/*****************公共接口**********************/ public interface ITest { public void addStudent(String Name); }
2、委托类,对接口的实现
/******************委托类**********************/ public class Test implements ITest { /** * 执行给定名字的任务。这里打印出学生姓名,并休眠500ms模拟任务执行了很长时间 */ @Override public void addStudent(String Name) { System.out.println("学生姓名:"+Name); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }
3、代理类,将委托类的行为表现出来
/**************代理类*******************/ public class ProxyTest implements ITest { // 代理类持有委托类的引用 <span style="color:#ff0000;">private Test delegate;</span> public ProxyTest(<span style="color:#ff0000;">Test delegate</span>) { this.delegate = delegate; } /** * 将请求分派给委托类执行,记录任务执行前后的时间,时间差即为任务的处理时间 */ @Override public void addStudent(String Name) { long stime = System.currentTimeMillis(); // 将请求分派给委托类处理 delegate.addStudent(Name); long ftime = System.currentTimeMillis(); System.out.println("执行任务耗时" + (ftime - stime) + "毫秒"); } }
4、代理类工厂
/******** 代理类工厂 ********/ public class TestFactory { public static ITest getInstance() { //对客户类来说,其并不知道返回的是代理类对象还是委托类对象 return new ProxyTest(new Test()); } }
5、客户端调用
public class Client { /** * @param args */ public static void main(String[] args) { ITest proxy = TestFactory.getInstance(); proxy.addStudent("好学生"); } }
那静态代理有什么优缺点呢?为什么会有动态代理产生呢?
优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。
缺点:
1)代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。
2)如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度
而动态代理恰恰弥补了静态代理的缺点,下面看下动态代理:静态代理与动态代理二