代理模式定义:为其他对象提供一种代理以控制对这个对象的访问。
上面类图中有一个订单接口类(OrderService)、一个订单实现类(OrderServiceImpl),订单模块的业务相对复杂和重要,如果这时候要在方法执行前后加上日志,就可以新增一个代理类来实现,而不用改动原来OrderServcieImpl核心业务逻辑代码。
代理模式角色
抽象角色(Subject):声明了目标对象和代理对象共同接口。
具体角色(RealSubject): 代理对象所代表的真实对象。
代理角色(Proxy):代理对象内部含有对真实对象的引用,与真实对象有相同的接口以便在任何时候都可以代替真实对象,同时它可以在执行真实对象操作时附加其它操作。
静态代理见上面例子
优点:没有侵入原代码
缺点:不同的接口要有不同的代理类实现类就会很冗余。
在运行时生成动态代理类,是基于Java的反射机制实现。
java.lang.reflect.Proxy: 调用newProxyInstance
得到某一对象的代理对象。
- public static Object newProxyInstance(ClassLoader loader,
- Class>[] interfaces,
- InvocationHandler h)
loader:指明生成代理对象使用哪个类装载器。
Class>[]: 指明哪个对象的代理对象。
InvocationHandler:指明这个代理对象要做什么事。
java.lang.reflect.InvocationHandler:代理实例调用处理程序一个接口。
代码:实现InvocationHandler接口的invoke方法,加入要处理的逻辑,客户端调用时先通过Proxy获取代理类对象。
优点:仅依赖于JDK代码实现简单。
缺点:必须实现接口的业务类才能生成代理对象。
CGLIB是一个强大的代理工具包,被广泛应用于AOP框架中以提供方法拦截操作,它的底层用ASM来操作字节码来生成类,需要注意CGLib与ASM版本的对应关系。
优点:不需要实现接口,可以对类直接进行代理。