|
今天在单位没事看JAVA核心知识点的时候看到了AOP的讲解部分,正好有讲解AOP动态代理章节顺便就参考一下其他资料 和API 写了一下例子分享一下。
说到动态代理就要从静态代理开始说起:
静态代理:
静态代理程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系早已确定好了。具体了代码示例我就不写了。
静态代理类的优缺点:
优点:只关心自己的业务类。附加功能有代理类完成。
缺点:1、代理对象的一个接口只服务一种类型的对象。程序规模变大将无法胜任了。
2、接口增加方法,实现类也要增加方法,所有代理类都将修改。
问题引申:静态代理需要委托类已存在且知晓,而是先不知的委托类静态代理将无法实现。此时我们就将需要动态代理。
动态代理类图:
动态代理类图
动态代理类定义:
动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类,该类具有下面描述的行为。 代理接口 是代理类实现的一个接口。 代理实例 是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序 对象,它可以实现接口 InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方法调用的结果返回。
Spring实现动态代理方式:
Spring提供了两种方式来生成代理对象: JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK动态代理技术,否则使用Cglib来生成代理。 本片只探究 JDKProxy实现。
JDK动态接口代理
JDK动态代理主要涉及到java.lang.reflect包中的一个类:Proxy和一个接口InvocationHandler。通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编制在一起。Proxy利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。
InvocationHandler:API帮助文描述
英文描述:InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.
中文翻译:每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。
Object invoke(Object proxy,
Method method,
Object[] args)
throws Throwable
参数解释:
proxy -指代所代理的那个真实对象
method –指代所要调用真实对象的某个方法的Method对象。
args –指代调用真实对象某个方法时接受的参数。
Proxy :解释
使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy 实例
动态代理最重要方法:newProxyInstance
newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
参数:
loader -一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces -一个Interface对象的数组,表示的是将要给需要代理的对象提供一组什么接口,如果提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样就能调用这组接口中的方法了
h -一个InvocationHandler对象,表示的是当这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
具体实现:代码结构
定义业务逻辑接口:Subject
接口
实现业务逻辑类:RealSubject
实现
实现代理类:动态代理类就是实现 InvocationHandler 接口,增强方法都写在这个类下面了。
动态代理类
客户端调用:
客户端调用
运行结果:
运行结果
代码优化:客户端每次都需要自己创建代理对象,我们将创建代理对象封装到代理实现类当中。
优化代理类,将生成代理对象移到这来
客户端代码优化:
客户端不需要创建代理类了
运行结果:
动态代理运用场景:
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Authentication 权限
Caching 缓存
Transactions 事务
感谢阅读!!!给个关注 评论 转发 行不行┭┮﹏┭┮
求关注! |
|