JDK动态代理:目标对象必须是某个接口的实现,通过在运行期间动态的创建(代理类)来完成对目标对象的代理
接口:
public interface Person {
public void talk();
}
目标类:
public class Student implements Person {
@Override
public void talk() {
System.out.println("Students is talking");
}
}
代理类:
public class JdkProxy implements InvocationHandler {
private Object target;
public JdkProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置通知----");
Object obj=method.invoke(target,args);
System.out.println("后置通知----");
return obj;
}
}
在main函数中测试jdk动态代理:
public static void main(String[] args) {
//将内存中生成的代理类Class文件输出出来
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
Student student=new Student();
Person person= (Person) Proxy.newProxyInstance(student.getClass().getClassLoader(),student.getClass().getInterfaces(),new JdkProxy(student));
person.talk();
}
输出结果
前置通知----
Students is talking
后置通知----
生成的代理class的核心方法:
public final class $Proxy0 extends Proxy implements Person {...}
public final void talk() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
发现super.h.invoke(this, m3, (Object[])null);
验证一下,生成的动态代理是$Proxy0(字节码形式) h是我们创建的JdkProxy类
System.out.println("-------------");
Field field=person.getClass().getSuperclass().getDeclaredField("h");
field.setAccessible(true);
Object o=field.get(person);
System.out.println(o.getClass());
输出结果
-------------
class jdk.JdkProxy
CGLIB动态代理:在运行期间生成的代理对象是针对目标类扩展的子类
public class Student{
public void say() {
System.out.println("我是学生...");
}
}
代理类
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("===============");
return methodProxy.invokeSuper(o,objects);
}
}
public static void main(String[] args) {
//CGLIB动态代理生成的Class代理输出出来
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D://");
Enhancer enhancer=new Enhancer(); //创建Enhancer对象
enhancer.setSuperclass(Student.class);//用Enhancer对象设置代理类的父类(被代理类)
enhancer.setCallback(new CglibProxy());//创建回调对象(回调类实现 MethodInterceptor 接口)
Student student= (Student) enhancer.create();//创建代理对象是目标类子类
student.say();
}
生成class文件 及 主要方法
public class Student$$EnhancerByCGLIB$$96190564 extends Student implements Factory {...}
public final void say() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$say$0$Method, CGLIB$emptyArgs, CGLIB$say$0$Proxy);
} else {
super.say();
}
}
//可以看出来是根据CGLIB$CALLBACK_0这个属性来决定调用say()的
//输出一下 CGLIB$CALLBACK_0 是从哪里得到的
System.out.println("============");
Field field=student.getClass().getDeclaredField("CGLIB$CALLBACK_0");
field.setAccessible(true);
Object o=field.get(student);
System.out.println(o.getClass());
我是学生...
============
class CglibProxy
可以看出就是原来的回调代理类