前言
什么是动态代理呢?动态代理指的是在实现阶段不需要关心代理谁,而是在运行阶段才指定哪一个对象。
动态代理示例
首先要介绍一下JDK提供的一个动态代理接口 InvocationHandler。这个接口的用途在于对代理类的方法进行代理,我们先实现InvocationHandler接口:
1 public class ConsumerHandler implements InvocationHandler { 2 3 private Object proxiedInstance = null; 4 5 public ConsumerHandler(Object proxiedInstance) { 6 this.proxiedInstance = proxiedInstance; 7 } 8 9 @Override 10 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 11 12 Object proxyInstance = method.invoke(this.proxiedInstance, args); 13 return proxyInstance; 14 } 15 }
第3行:声明被代理的对象实例。
第5行:构造行数被代理对象作为形式参数。
第10行-14行:调用被代理的方法。
消费者抽象接口和消费者真实角色都没有改动,代码如下图所示:
1 public interface IConsumer { 2 3 public void login(String name, String password); 4 5 public void order(); 6 7 public void pay(); 8 9 }
1 public class RealConsumer implements IConsumer { 2 3 private String name = null; 4 5 public RealConsumer(String name){ 6 this.name = name; 7 } 8 9 @Override 10 public void login(String name, String password) { 11 12 System.out.println("登录用户["+name+"]登陆成功"); 13 } 14 15 @Override 16 public void order() { 17 18 System.out.println("登录账号:"+ this.name +"生成订单成功"); 19 20 } 21 22 @Override 23 public void pay() { 24 25 System.out.println("登录账号:"+ this.name +"订单支付成功"); 26 27 } 28 29 }
OK。这个都没什么问题,最后我们再看看一下动态代理的场景类:
1 public class Client { 2 3 public static void main(String[] args) { 4 IConsumer consumer = new RealConsumer("抒尽"); 5 6 ConsumerHandler consumerHandler = new ConsumerHandler(consumer); 7 8 ClassLoader classLoader = consumer.getClass().getClassLoader(); 9 10 Object o = Proxy.newProxyInstance(classLoader, new Class[]{IConsumer.class}, consumerHandler); 11 IConsumer proxy = (IConsumer)o; 12 13 proxy.login("shujin", "123456"); 14 proxy.order(); 15 proxy.pay(); 16 } 17 }
第4行,定义一个真实消费者[抒尽]
第6行,定义一个handler
第8行,获取真实角色的类加载器
第10行-11行,动态产生一个代理者
第13行-15行,使用代理者来访问。
使用动态代理,我们并没有手工去创建一个代理类,更加没有代理类实现抽象接口。这就是动态代理的强大功能,如果我们需要变更需求,只需要修改动态代理实现类即可。
如果使用InvovationHandler实现动态代理。要产生某个类的代理,这个类必须要有接口。