学习spring的时候,涉及到的AOP(面向切面编程),其原理就是动态代理。
在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)
、另一个则是 Proxy(Class)
,这一个类和接口是实现我们动态代理所必须用到的。
每一个动态代理类都必须要实现InvocationHandler
这个接口,并且每个代理类的实例都关联到了一个handler
,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler
这个接口的invoke
方法来进行调用。我们来看看InvocationHandler
这个接口的唯一一个方法invoke
方法:
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
proxy: 指代我们所代理的那个真实对象
method: 指代的是我们所要调用真实对象的某个方法的Method对象
args: 指代的是调用真实对象某个方法时接受的参数
Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法:
`public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException`
loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
定义一个代理类
`
class InvokeHandler implements InvocationHandler {
// 需要代理的对象
private Object target;
public InvokeHandler(Object t) {
target = t;
}
/*
* (non-Javadoc)
*
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[])
*
* @proxy:指代我们所代理的那个真实对象
*
* @method:指代的是我们所要调用真实对象的某个方法的Method对象
*
* @args:指代的是调用真实对象某个方法时接受的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 打印代理对象
System.out.print(target);
// 打印代理方法名称
System.out.print("." + method.getName() + "(");
// 打印代理方法参数
if (args != null) {
for (int i = 0; i < args.length; i++) {
System.out.print(args[i]);
if (i < args.length - 1) {
System.out.print(", ");
}
}
}
System.out.println(")");
// 调用代理方法
return method.invoke(target, args);
}
}
`
调用代理类实现动态代理
`
Integer a = 1;
// 配置第一个代理aProxyInstance,用于代理Integer类型的a。
InvocationHandler aHandler = new InvokeHandler(a);
// 其中第一个参数null表示使用默认的类加载器,
// 第二个参数表明需要代理类实现的接口,
// 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
// 第三个参数为调用处理器类
// 配置第一个代理bProxyInstance,用于代理Integer类型的b。
Object aProxyInstance = Proxy.newProxyInstance(null, new Class[] { Comparable.class }, aHandler);
Integer b = 2;
InvocationHandler bHandler = new InvokeHandler(b);
Object bProxyInstance = Proxy.newProxyInstance(null, new Class[] { Comparable.class }, bHandler);
Comparable aComparable = (Comparable) aProxyInstance;
Comparable bComparable = (Comparable) bProxyInstance;
System.out.println(aComparable.compareTo(b));
System.out.println(bComparable.compareTo(a));
`
控制台打印
1.compareTo(2)
-1
2.compareTo(1)
1