特点
1 - 基于接口
2 - 不能代理枚举对象
相关类和接口
Proxy -> 生成代理对象
InvocationHandler -> 实现增强功能
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Person{
public void sayHello(String name);
}
class Tom implements Person{
@Override
public void sayHello(String name) {
System.out.println("Hello" + name);
}
public void eat(){
System.out.println("我要吃饭");
}
@Override
public String toString(){
return "tom";
}
}
class ProxyHandler implements InvocationHandler{
private Object target;
public ProxyHandler(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//System.out.println(proxy.toString());
//方法签名public abstract void com.macro.mall.config.Person.sayHello(java.lang.String)
System.out.println(method.toString());
//方法参数
System.out.println(args[0]);
System.out.println("前置处理");
Object result = method.invoke(target, args);
System.out.println("执行结果是" + result);
System.out.println("后置处理");
return null;
}
}
public class A {
/**
* JDK动态代理是基于【接口】的,被代理对象必须实现接口
* 这也决定的JDK动态代理无法代理类独有的方法
* 只能代理接口中包含的方法
*
* JDK动态代理的增强功能具有通用性
* ProxyHandler代表一种增强方法,它可以应用到Person接口,也可以应用到Animal接口
*
* 注意点
* 1 - 被代理对象必须实现一个或多个接口
* 2 - 不能代理枚举对象
*/
public static void main(String[] args) {
Person tom = new Tom();
ProxyHandler proxyHandler = new ProxyHandler(tom);
//返回代理对象
//这里的Person只能是接口,不能是类,否则报错ClassCastException
//通过前两个参数获得被代理对象,通过第三个参数获得增强功能
Person o = (Person)Proxy.newProxyInstance(tom.getClass().getClassLoader(),//【被代理类,即Tom】的类加载器
tom.getClass().getInterfaces(),//【被代理接口,即Person】的接口集合
proxyHandler);//代理对象
o.sayHello("zcx");
//无法代理类中独有的方法
//o.eat();
}
}
和CGLib不同之处
JDK动态代理 CGLib
原理 反射 继承
注意 被代理类必须实现接口 被代理类不能被final修饰,因为代 理对象要继承被代理对象