在使用Spring框架的时候i,我们都知道IOC和AOP,IOC就不多说了,要想更好的去理解学习AOP,就需要去理解其底层原理,而AOP的实现原理就是动态代理机制,那么什么是动态代理呢?
在JAVA动态代理中,有一个重要的接口和类(InvocationHandler接口和Proxy类),在实现动态代理的时候此接口和类是必不可少的。
JDK文档中对InvocationHandler的描述是:代理实例的调用处理程序 实现的接口。
我们先来看InvocationHandler接口源码
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
此接口中只提供了这一个方法,其中
proxy -在其上调用方法的代理实例;
method -对应于在代理实例上调用的接口方法的 Method
实例;
args -调用真是对象某个方法时接受的参数。
再看Proxy类,此类中提供了多个方法,此处我们在讲本文中需要用到的方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
loader - 定义代理类的类加载器 ;
interfaces
- 代理类要实现的接口列表 ;
h
- 指派方法调用的调用处理程序。
通过实例来了解动态代理的实现:
接口:
public interface DemoDynamicProxy {
public void say0();
public void say1();
public void say2();
public void say3();
}
实现类:
public class DemoDynamicProxyImpl implements DemoDynamicProxy {
@Override
public void say0() {
System.out.println("this is say0");
}
@Override
public void say1() {
System.out.println("this is say1");
}
@Override
public void say2() {
System.out.println("this is say2");
}
@Override
public void say3() {
System.out.println("this is say3");
}
}
动态代理类,此时我们需要实现InvocationHandler接口:
public class DynamicProxy implements InvocationHandler{
//需要代理的真实对象
private Object obj;
//自定义构造方法,给代理对象赋值
public DynamicProxy(Object obj){
this.obj = obj;
}
//取得代理对象
public static Object getProxy(Object obj){
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new DynamicProxy(obj));
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理对象前需要做的操作
System.out.println("-----------before");
//代理类所调用的方法
System.out.println("Method:"+method);
Object result = method.invoke(obj, args);
//代理对象之后需要做的操作
System.out.println("-----------after");
return result;
}
}
测试类:
public static void main(String[] args) {
//需要代理的真实对象
DemoDynamicProxy ddp = new DemoDynamicProxyImpl();
DemoDynamicProxy dymp = (DemoDynamicProxy) DynamicProxy.getProxy(ddp);
System.out.println("需要代理的类:"+ddp.getClass().getName());
dymp.say0();
System.out.println("===========分割线===========");
dymp.say1();
}
控制台打印效果:
需要代理的类:com.spring.demo.spring_demo.service.proxy.DemoDynamicProxyImpl
-----------before
Method:public abstract void com.spring.demo.spring_demo.service.proxy.DemoDynamicProxy.say0()
this is say0
-----------after
===========分割线===========
-----------before
Method:public abstract void com.spring.demo.spring_demo.service.proxy.DemoDynamicProxy.say1()
this is say1
-----------after