动态代理
AOP的原理就是Java的动态代理机制,在Java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。
动态代理的基础 : 必须有接口.
Java中使用接口来定义统一的行为规范 : 接口
动态代理作用 : 拦截和控制 被代理对象
的所有行为.
Proxy 代理类
Class Proxy 代理类 是在运行时创建的实现指定的接口列表(称为代理接口)的类 。 代理实例是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序对象,它实现接口InvocationHandler
。 通过其代理接口之一的代理实例上的方法调用将被分派到实例调用处理程序的invoke
方法
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
返回指定接口的代理实例,该代理实例将方法调用分派给指定的调用处理程序。
InvocationHandler 调用处理器接口
Interface InvocationHandler 每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke
方法。
案例
消费者和生产商之间加入了代理商,代理商会收取代理费。
动态代理的特点
字节码随用随创建,随用随加载。它与静态代理的区别也在于此。因为静态代理是字节码一上来就创建好,并完成加载。装饰者模式就是静态代理的一种体现。动态代理在不修改源码的基础上对方法增强。
动态代理常用的两种方式
基于接口的动态代理提供者:
JDK 官方的 Proxy 类。
要求:被代理类最少实现一个接口。
基于子类的动态代理
提供者:第三方的 CGLib,如果报 asmxxxx 异常,需要导入 asm.jar。
要求:被代理类不能用 final 修饰的类(最终类)。
基于接口的动态代理
- 涉及的类:Proxy
- 提供者:JDK官方
- 如何创建代理对象
- 使用Proxy类中的newProxyInstance方法
- 创建代理对象的要求:被代理对象最少实现一个接口,如果没有则不能使用
- newProxyInstance方法的参数:
- ClassLoader:类加载器:用于加载代理对象字节码的,和被代理对象使用相同的类加载器。固定写法
- Class[]:字节码数组:用于让代理对象和被代理对象有相同的接口。固定写法。
- InvocationHandler:代理增强:用于写如何代理。一般写一个接口的实现类,通常都是内部匿名类,但不必须。此接口的实现类都是谁用谁写。
1 | // IProducer.java |
1 | // Producer.java |
1 | // Client.java |
基于子类的动态代理
涉及的类:Enhancer
提供者:第三方cglib库
如何创建代理对象
- 使用Enhancer类中的create方法
- 创建代理对象的要求:被代理类不能是最终类
- create方法的参数:
- Class:字节码: 用于指定被代理对象的字节码。
- Callback:代理增强:用于写如何代理。一般写一个接口的实现类,通常都是内部匿名类,但不必须。 此接口的实现类都是谁用谁写。 一般写的都是该接口的子接口实现类:MethodInterceptor
1 | // Producer.java\ |
1 | // Client.java |
解决案例中的问题
案例会在下一篇中做总结回顾,这里新建factory/BeanFactory.java,将业务层与事务控制完全分离。
1 | package com.gsynf.factory; |
注:转载文章请注明出处,谢谢~