1.什么是动态代理?
在运行时创建目标类,可以调用和扩展目标类的方法。
动态代理利用Java的反射技术生成字节码,在运行时创建一个实现某些给定接口的新类及其实例。注意:这里代理的时接口,不是类和抽象类。
2.动态代理的应用场景?
Dubbo
AOP in Spring
3.怎么用动态代理?
下面是应用动态代理的实例:
3.1定义一个接口Interface
public interface Interface {
String dosomething();
}
3.2定义一个RealObject类,实现Interface接口,这个类是真实的对象
public class RealObject implements Interface{
public String dosomething(){
System.out.println("dosomething");
return "dosomething()";
}
}
3.3定义一个代理类的调用处理程序,每个代理类的调用处理程序都必须实现
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxyHandle implements InvocationHandler {
//代理类中的真实对象
private Object proxied;
//构造函数,给我们的真实对象赋值
public DynamicProxyHandle(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//在真实的对象执行之前我们可以添加自己的操作
System.out.println("before invoke。。。");
//对接口的调用将被重定向为对代理的调用
Object invoke = method.invoke(proxied, args);
//在真实的对象执行之后我们可以添加自己的操作
System.out.println("after invoke。。。");
return invoke;
}
}
3.4.客户端测试类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class TestHandler {
public static void main(String[] args) {
//要代理的真实对象
Interface face = new RealObject();
//代理对象的调用处理程序,我们将要代理的真实对象传入代理对象的调用处理的构造函数中,最终代理对象的调用处理程序会调用真实对象的方法
InvocationHandler handler = new DynamicProxyHandle(face);
/**
* 通过Proxy类的newProxyInstance方法创建代理对象,我们来看下方法中的参数
* 第一个参数:people.getClass().getClassLoader(),使用handler对象的classloader对象来加载我们的代理对象
* 第二个参数:people.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法
* 第三个参数:handler,我们将代理对象关联到上面的InvocationHandler对象上
*/
Interface proxy = (Interface)Proxy.newProxyInstance(face.getClass().getClassLoader(), face.getClass().getInterfaces(), handler);
System.out.println(proxy.dosomething());
}
}
3.5运行结果如下:
before invoke。。。
dosomething
after invoke。。。
dosomething()
4.jdk 动态代理核心思想
通过实现被代理类的所有接口,生成一个字节码文件后构造一个代理对象,通过持有反射构造被代理类的一个实例,
再通过invoke反射调用被代理类实例的方法,来实现代理。