设计模式——动态代理
2017-10-14 11:16
253 查看
之前讲过,静态代理的两个缺点:1. 需要手动建立代理类,当需要代理的对象增多时,会创建多个代理类 2. 代理与被代理对象实现同一接口,对象间耦合度太高。那么动态代理是如何解决这两个问题的呢?
1. 动态代理简介:
首先先说个结论,动态代理主要是通过反射机制动态创建的。
JDK的reflect包中提供了Proxy类来获得动态代理,Proxy类中有一个非常重要的方法Proxy.newProxyInstance:
Proxy.newProxyInstance的参数介绍:
-ClassLoader loader:被代理类的类加载器,其实我感觉(包括也是《大话设计模式》一书作者的想法)这个参数没啥用,因为传入的总是被代理对象的类加载器啊。。。
-Class<?>[] interfaces:被代理类的接口。 可以选择性地代理接口。
-InvocationHandler h:InvocationHandler的实现类。这是实现动态代理最重要的一个类
2. InvocationHandler及具体代码实现(仍以Business这个接口为例)
InvocationHandler接口中只有一个方法invoke:
invoke方法的参数介绍:
- Objectproxy:指代理对象,其实这个参数在方法中根本没用到,不知道干嘛要暴露出来。。。
- Methodmethod:被代理的方法
- Object[]args:代理方法的参数
3. 跑下测试用例:
然后看下结果:
4. 一点小总结:
开头说过静态代理的缺点,可以看到,动态代理比较好地解决了手动创建代理的问题。并且,我们看到代理类和被代理类不需要实现同一个接口,这些修改原接口只会影响到被代理类,类之间的耦合度降低了。
1. 动态代理简介:
首先先说个结论,动态代理主要是通过反射机制动态创建的。
JDK的reflect包中提供了Proxy类来获得动态代理,Proxy类中有一个非常重要的方法Proxy.newProxyInstance:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException{...}
Proxy.newProxyInstance的参数介绍:
-ClassLoader loader:被代理类的类加载器,其实我感觉(包括也是《大话设计模式》一书作者的想法)这个参数没啥用,因为传入的总是被代理对象的类加载器啊。。。
-Class<?>[] interfaces:被代理类的接口。 可以选择性地代理接口。
-InvocationHandler h:InvocationHandler的实现类。这是实现动态代理最重要的一个类
2. InvocationHandler及具体代码实现(仍以Business这个接口为例)
package designpatterns.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by Olive on 2017/9/11. * 动态代理:运用反射机制动态创建而成 */ public class BusinessDynamicProxyHandler implements InvocationHandler { // 被代理的对象 private Object object; public BusinessDynamicProxyHandler(Object object){ this.object = object; } // proxy指代理类,method指被代理的方法,args指方法的参数数组 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); if(methodName.equals("transaction")){ System.out.println("start process a transaction"); } // 去调用被代理对象的方法 Object result = method.invoke(object, args); return result; } // 生成代理对象 public Object getProxy(){ return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this); } }
InvocationHandler接口中只有一个方法invoke:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
invoke方法的参数介绍:
- Objectproxy:指代理对象,其实这个参数在方法中根本没用到,不知道干嘛要暴露出来。。。
- Methodmethod:被代理的方法
- Object[]args:代理方法的参数
3. 跑下测试用例:
package designpatterns.proxy; import java.lang.reflect.Field; /** * Created by Olive on 2017/9/11. */ public class ProxyDynamicTest { public static void main(String[] args){ CarBusiness carBusiness = new CarBusiness(); BusinessDynamicProxyHandler proxyHandler = new BusinessDynamicProxyHandler(carBusiness); // 获得代理,可以发现代理并不需要实现Business接口,所以之后接口的修改并不会影响代理类的实现 // 所以完成了解耦 Business businessProxy = (Business) proxyHandler.getProxy(); // 调用代理方法,实际通过调用invoke方法来执行相应的方法 businessProxy.transaction(); } }
然后看下结果:
start process a transaction I want to buy a car!
4. 一点小总结:
开头说过静态代理的缺点,可以看到,动态代理比较好地解决了手动创建代理的问题。并且,我们看到代理类和被代理类不需要实现同一个接口,这些修改原接口只会影响到被代理类,类之间的耦合度降低了。
相关文章推荐
- 动态代理设计模式
- 设计模式之动态代理模式
- 代理设计模式之静态代理与动态代理(超..)详解
- 设计模式之动态代理
- Android开发中无处不在的设计模式——动态代理模式
- 设计模式02-动态代理模式
- 设计模式之动态代理
- 设计模式之 动态代理模式
- 设计模式之动态代理模式
- 0104 Java设计模式03-动态代理(实战篇JDK和cglib)【进阶】
- Java的反射,动态代理,模版设计模式,
- Java设计模式之动态代理模式实例分析
- java设计模式_代理模式_动态代理(带例子)
- Java设计模式之动态代理
- 设计模式 —— 动态代理(Dynamic Proxy)
- 设计模式--对代理模式的思考之java动态代理
- 深度解析JAVA动态代理设计模式
- Java设计模式学习06——静态代理与动态代理
- 设计模式--CGLib动态代理的实现与解析
- Java-马士兵设计模式学习笔记-代理模式-动态代理 修改成可以任意修改代理逻辑