Java反射之JDK动态代理实现简单AOP
2010-04-04 13:52
1331 查看
JDK动态代理实现简单AOP
JDK
动态代理是
java
反射的一个重要特性。它在某种方面为
java
提供了动态性的特性,给应用带来了无限的空间。大名鼎鼎的
Hessian
、
Spring AOP
基于动态代理实现。本文将简单的介绍
JDK
动态代理使用。
关于代理模式
代理模式是非常常用的一种设计模式,在我们的应用中经常被使用。一般场景是,我们有一个现成的类,它的功能比较的完善了,但是还是存在某些欠缺,这个时候我们需要去扩展一些新的功能,但又不想去重造轮子,这个时候可以使用代理类来替代原来的目标类,通过组合的模式,增加一种为目标类增加一些额外的功能。
代理模式的类结构图一般如下:
图1:代理模式类结构图
图2:代理模式序列图
JDK
动态代理
所谓
JDK
动态代理就是在运行时动态生成红色的代理类的过程。和静态代理不一样的地方是静态代理在编译期就要完成代理类
的实现。那么动态代理是如何实现的呢?
根据下面的例子,一步一步来看。
假设有这样一个接口
Speak:
实现类
PeopleSpeak.
当我们去调用
PersonSpeak
的
sayHello
的时候,很显然是输出
hello
。现在我们需要通过动态代理在运行时动态的生成
Speak
的代理类,并在调用
sayHello
方法的前后做一些输出。完成类似
aop
的功能。
根据以上的思路,我们需要有一个
PersonSpeak
的代理类,它持了
PersonSpeak
的对象,这样就能很方便的完成这个任务。如果用静态代理实现显然是很简单,那么用动态代理如何实现呢?
这个时候我们可以使用
java
反射里的
Proxy
类。此类是
JDK
动态代理的核心类。
Proxy
类拥有一个在运行期动态创建类的功能。动态的去创建一个
Speak
的子类,同时该子类持有
PersonSpeak
类的一个实例,该子类的功能就是实现上述第一部分代理类的功能。
关于
java
反射的
Method
、
Field
、
Class
、
Construtor
等这里不做介绍,重点介绍
Proxy和
InvocationHandler
类。
Proxy和InvocationHandler
类简介
Proxy
类提供了非常重要的方法,该方法能够动态的生成几个接口的实现类。具体的实现过程由
ProxyGenerator
类来实现,这是比较低层的一个类,这里不做过多描述。同时该动态类需要持有一个实现了
InvocationHandler
接口的子类对象。
InvocationHandler
接口的子类对象是我们目标类的又一层代理。对于接口里面的每个方法实现,都是通过调用
InvocationHandler
接口的子类对象的反射调用。也就是说动态代理类实际上是
InvocationHandler
子类对象的一个代理。那么
InvocationHandler
子类对象有时我们目标类的代理。通过这样层层代理我们就能实现上述的功能了。这句话可能不是很好理解,但是确实就是这么实现的,也许通过下面的图就能更好的理解:
图3:JDK动态代理调用过程
可以从上图看出来,
JDK
动态反射并不是那么简单的一层代理,而是通过层层代理,最终通过
Method
的反射来调用目标对象的方法,而
aop
的实现可以放在
InvocationHandler
的是实现类里。
那么根据上述关于动态代理的简介,要实现
PersonSpeak
的
aop
,需要做两件事情
1.
实现一个持有
Speak
对象的
InvocationHandler
子类,改子类通过
Mechod
反射调用
PersonSpeak
的方法,并在调用方法前后实现
aop
功能。
2.
实现一个能动态创建
Speak
子类的代理类工厂,改工厂能动态的创建
Speak
子类。
具体实现如下:
1.
SpeakInvocationHandler (
实现
InvocationHandler
接口
)
可以看出该类的
invoke
方法实现
aop
的关键,所有方法都是通过
invoke
来调用,
invoke
内部通过反射来调用目标对象
target
,同时在调用前后实现了
aop
。
2.
ProxyFactory
ProxyFactory
主要是通过反射的
Proxy
类动态的去创建接口的子类,同时该子类是
InvocationHandler
的一个代理,所有的方法实现,都是通过
InvocationHandler
代理来调用。
最后来看下
Main
函数:
得到的输出结果如下:
sayHello invoked!
hello
sayHello return!
从输出结果可以看出红色的输出部分正是我们通过动态代理来实现的。通过如上的过程完成了正果动态代理的过程。
除了实现
AOP
,动态代理还可以用于实现远程服务代理。比如说
Hessian
就是通过动态创建远程服务代理类来调用远程服务,从而使应用对远程服务透明化。
Hessian
调用过程如下:
图4:Hessian远程服务调用过程
总结
JDK
动态代理是
java
反射的一个非常重要的特性,
JDK
动态代理类还可以用来作为
SOAP
的远程服务代理类,总之它在某种程度上提供了
java
的动态性的特点,为应用提供了很大的灵活性。
JDK
动态代理是
java
反射的一个重要特性。它在某种方面为
java
提供了动态性的特性,给应用带来了无限的空间。大名鼎鼎的
Hessian
、
Spring AOP
基于动态代理实现。本文将简单的介绍
JDK
动态代理使用。
关于代理模式
代理模式是非常常用的一种设计模式,在我们的应用中经常被使用。一般场景是,我们有一个现成的类,它的功能比较的完善了,但是还是存在某些欠缺,这个时候我们需要去扩展一些新的功能,但又不想去重造轮子,这个时候可以使用代理类来替代原来的目标类,通过组合的模式,增加一种为目标类增加一些额外的功能。
代理模式的类结构图一般如下:
图1:代理模式类结构图
图2:代理模式序列图
JDK
动态代理
所谓
JDK
动态代理就是在运行时动态生成红色的代理类的过程。和静态代理不一样的地方是静态代理在编译期就要完成代理类
的实现。那么动态代理是如何实现的呢?
根据下面的例子,一步一步来看。
假设有这样一个接口
Speak:
package proxy; public interface Speak { public void sayHello(); }
实现类
PeopleSpeak.
package proxy; public class PersonSpeak implements Speak { public void sayHello() { System.out.println("hello"); } }
当我们去调用
PersonSpeak
的
sayHello
的时候,很显然是输出
hello
。现在我们需要通过动态代理在运行时动态的生成
Speak
的代理类,并在调用
sayHello
方法的前后做一些输出。完成类似
aop
的功能。
根据以上的思路,我们需要有一个
PersonSpeak
的代理类,它持了
PersonSpeak
的对象,这样就能很方便的完成这个任务。如果用静态代理实现显然是很简单,那么用动态代理如何实现呢?
这个时候我们可以使用
java
反射里的
Proxy
类。此类是
JDK
动态代理的核心类。
Proxy
类拥有一个在运行期动态创建类的功能。动态的去创建一个
Speak
的子类,同时该子类持有
PersonSpeak
类的一个实例,该子类的功能就是实现上述第一部分代理类的功能。
关于
java
反射的
Method
、
Field
、
Class
、
Construtor
等这里不做介绍,重点介绍
Proxy和
InvocationHandler
类。
Proxy和InvocationHandler
类简介
Proxy
类提供了非常重要的方法,该方法能够动态的生成几个接口的实现类。具体的实现过程由
ProxyGenerator
类来实现,这是比较低层的一个类,这里不做过多描述。同时该动态类需要持有一个实现了
InvocationHandler
接口的子类对象。
InvocationHandler
接口的子类对象是我们目标类的又一层代理。对于接口里面的每个方法实现,都是通过调用
InvocationHandler
接口的子类对象的反射调用。也就是说动态代理类实际上是
InvocationHandler
子类对象的一个代理。那么
InvocationHandler
子类对象有时我们目标类的代理。通过这样层层代理我们就能实现上述的功能了。这句话可能不是很好理解,但是确实就是这么实现的,也许通过下面的图就能更好的理解:
图3:JDK动态代理调用过程
可以从上图看出来,
JDK
动态反射并不是那么简单的一层代理,而是通过层层代理,最终通过
Method
的反射来调用目标对象的方法,而
aop
的实现可以放在
InvocationHandler
的是实现类里。
那么根据上述关于动态代理的简介,要实现
PersonSpeak
的
aop
,需要做两件事情
1.
实现一个持有
Speak
对象的
InvocationHandler
子类,改子类通过
Mechod
反射调用
PersonSpeak
的方法,并在调用方法前后实现
aop
功能。
2.
实现一个能动态创建
Speak
子类的代理类工厂,改工厂能动态的创建
Speak
子类。
具体实现如下:
1.
SpeakInvocationHandler (
实现
InvocationHandler
接口
)
可以看出该类的
invoke
方法实现
aop
的关键,所有方法都是通过
invoke
来调用,
invoke
内部通过反射来调用目标对象
target
,同时在调用前后实现了
aop
。
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class SpeakInvocationHandler implements InvocationHandler { public Object target; SpeakInvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName() + " invoked!"); Object result = method.invoke(target, args); System.out.println(method.getName() + " return!"); return result; } }
2.
ProxyFactory
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class ProxyFactory { Class cls; InvocationHandler h; public ProxyFactory(String className, InvocationHandler h) { try { cls = Class.forName(className); this.h = h; } catch (ClassNotFoundException e) { e.printStackTrace(); } } public Object createProxyObject() { return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h); } }
ProxyFactory
主要是通过反射的
Proxy
类动态的去创建接口的子类,同时该子类是
InvocationHandler
的一个代理,所有的方法实现,都是通过
InvocationHandler
代理来调用。
最后来看下
Main
函数:
package proxy; import java.lang.reflect.InvocationHandler; public class ProxyTest { public static void main(String args[]) { Speak s = new PersonSpeak(); InvocationHandler h = new SpeakInvocationHandler(s); ProxyFactory proxyFactory = new ProxyFactory(PersonSpeak.class.getName(), h); Speak speakProxy = (Speak) proxyFactory.createProxyObject(); speakProxy.sayHello(); } }
得到的输出结果如下:
sayHello invoked!
hello
sayHello return!
从输出结果可以看出红色的输出部分正是我们通过动态代理来实现的。通过如上的过程完成了正果动态代理的过程。
除了实现
AOP
,动态代理还可以用于实现远程服务代理。比如说
Hessian
就是通过动态创建远程服务代理类来调用远程服务,从而使应用对远程服务透明化。
Hessian
调用过程如下:
图4:Hessian远程服务调用过程
总结
JDK
动态代理是
java
反射的一个非常重要的特性,
JDK
动态代理类还可以用来作为
SOAP
的远程服务代理类,总之它在某种程度上提供了
java
的动态性的特点,为应用提供了很大的灵活性。
相关文章推荐
- Java反射之JDK动态代理实现简单AOP
- Java反射之JDK动态代理实现简单AOP
- Java反射之JDK动态代理实现简单AOP
- 通过CGLIB实现AOP的浅析(顺便简单对比了一下JDK的动态代理)
- Java动态代理实现简单AOP
- Java JDK 动态代理(AOP)使用及实现原理分析
- 利用动态代理实现AOP的简单示例(JDK和cglib分别实现)
- Java JDK 动态代理(AOP)使用及实现原理分析
- Java动态代理之JDK实现和CGlib实现(简单易懂)
- Java动态代理之JDK实现和CGlib实现(简单易懂)火推笔记
- JAVA动态代理 和 Spring AOP 4种通知的简单实现
- Java动态代理模式jdk和cglib的2种实现以及二者的区别(AOP面向切面的前奏)
- Java动态代理之JDK实现和CGlib实现(简单易懂)
- Java JDK 动态代理(AOP)使用及实现原理分析
- 利用JAVA的动态属性之反射原理实现一个简单AOP容器 - AOP的实现原理分析
- JAVA JDK的动态代理反射实现
- Java JDK 动态代理(AOP)使用及实现原理分析
- 模拟实现Struts拦截器-蕴含着代理模式,AOP,工厂模式,依赖注入,Java 反射,动态构造等机制
- Java JDK动态代理(AOP)的实现原理与使用详析
- Java JDK 动态代理(AOP)使用及实现原理分析