设计模式之----动态代理

1、为什么需要动态代理呢? 什么情况下我们会用到动态代理?

(1)当我们需要对以前老的方法进行功能增强或者修改的时候,我们又不想去改动老代码,应为老代码很有可能会别人写的,这个时候我们可以使用动态代理;

(2)目标对象对我们不可见,就是我们不能直接使用目标对象,需要使用代理对象来完成功能调用;

(3)对需要增加事务的方法和类,可以使用动态代理,应为添加事务的代码是不变的,而且事务的代码跟我们的事业代码没有任何关联,如果将事务代码和业务代码写在同一个方法里面,会将代码变得冗余和加大耦合度;

我们使用动态代码模式就可以解决以上所有的问题,那么动态代码是不是很厉害呢;

虽然说我们是调用代理对象完成了功能,但是真正做事的还是目标对象;

比如我们学校100周年,校长想请刘德华来参加周年活动并唱一首歌,但是校长没有办法直接联系到刘德华;这个时候校长只能找到刘德华的助理,跟助理商量具体的安排,比如时间,地点,定金等情况;这个里面刘德华是目标对象,助理就是代理对象,校长相当于客户端;等校长跟助理把所有具体的细节都安排好了后,那么刘德华到时候,直接来唱歌就行了;具体做事的其实还是刘德华,并不是助理唱歌的,还是刘德华唱的歌;

2、创建一个动态代理对象的基本步骤(JDK);

(1)创建一个接口

public interface Servlet { public void sing(); }

(2)创建一个目标类实现该接口

public class StarLiu implements Servlet { @Override public void sing() { System.out.println("刘德华正在唱歌!!!!"); } }

(3)创建一个普通类,并实现InvocationHandler接口,实现invoke方法,invoke方法里面就是助理要做的事,增强目标对象方法的功能;

public class MyAgent implements InvocationHandler { //目标对象 private Object targer; public MyAgent(Object targer) { this.targer = targer; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("商量时间"); System.out.println("商量地点"); System.out.println("缴纳定金"); Object obj = method.invoke(targer, args); System.out.println("支付尾款"); return obj; } }

(4)使用Proxy类的newProxyInstance方法创建代理对象

public class MyTest { public static void main(String[] args) { Servlet servlet = (Servlet) Proxy.newProxyInstance( new StarLiu().getClass().getClassLoader(), new StarLiu().getClass().getInterfaces(), new MyAgent(new StarLiu())); servlet.sing(); } }