JDK动态代理
JDK动态代理,只能对实现了接口的类生成代理,而不是针对类,该目标类型实现的接口都将被代理。原理是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。实现步骤大概如下:
- 定义一个实现接口InvocationHandler的类
- 通过构造函数,注入被代理类
- 实现invoke( Object proxy, Method method, Object[ ] args)方法
- 在主函数中获得被代理类的类加载器
- 使用Proxy.newProxyInstance( )产生一个代理对象
- 通过代理对象调用各种方法
package com.package1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxy {
public static void main(String[] args){
//定义一个people作为被代(dai)理的实例
IPeople ple=new People();
//定义一个handler
InvocationHandler handle=new MyHandle(ple);
//获得类加载器
ClassLoader cl=ple.getClass().getClassLoader();
//动态产生一个代(dai)理,下边两种方法均可
// IPeople p=(IPeople) Proxy.newProxyInstance(cl, new Class[]{IPeople.class}, handle);
IPeople p=(IPeople) Proxy.newProxyInstance(cl, ple.getClass().getInterfaces(), handle);
//执行被代(dai)理者的方法。
p.func();
}
}
class MyHandle implements InvocationHandler{
//被代(dai)理的实例
Object obj=null;
//我要代(dai)理谁
public MyHandle(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("在调用方法之前执行的方法");
Object result=method.invoke(this.obj, args);
System.out.println("在调用方法之后执行的操作");
return result;
}
}
interface IPeople{
public void fun();
public void func();
}
//实际被代(dai)理的类
class People implements IPeople{
@Override
public void fun() {
System.out.println("这是fun方法");
}
@Override
public void func() {
System.out.println("这是func方法");
}
}
原理:
当执行到被代理者(委托类)的p.func();
方法时,会自动调用MyHandle 的invoke方法。–>原因:因为JDK根据委托接口动态生成的最终真正的代理类,它继承自Proxy并实现了我们定义的People接口,在实现People接口方法的内部,通过反射调用了MyHandle 的invoke方法。
优点:
- 我们的代理与具体哪个接口无关,我们只需要传递接口的实现类就行了
- 如果接口改变了,我们的代理类不需要做任何变动