package reflect;
import lombok.Data;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxyDemo {
interface Subject {
String request(String type);
}
@Data
static class RealSubject implements Subject {
private String name;
private int age;
public RealSubject (String name, int age) {
this.name = name;
this.age = age;
}
public String request(String type) {
System.out.println(type + "RealSubject request");
return type + "RealSubject request";
}
private void testChild() {
System.out.println("test child");
}//这个是为了测试私有方法不会被代理
}
static class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = method.invoke(target, args);
System.out.println("after");
return result;
}
}
public static void main(String[] args) {
testProxy();
// testReflect();
}
private static void testProxy() {
RealSubject realSubject = new RealSubject("cat",1);
InvocationHandler handler = new MyInvocationHandler(realSubject);
Subject proxySubject = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler);
//核心步骤是Class<?> cl = getProxyClass0(loader, intfs);这一步会生成$Proxy0,$Proxy0和Proxy有继承关系,并在此基础上定义了代理方法:request()
//而request()方法的实现,是在运行过程中动态代理自动生成的
Class<?> proxy = proxySubject.getClass();
Method[] methods = proxy.getMethods();
System.out.println(proxySubject.getClass().getSuperclass().getName());
String s = proxySubject.request("");
// int code = proxySubject.hashCode();
}
private static void testReflect() {
Class<?> realSubjectClass = RealSubject.class;
Method[] realSubjectClassMethods = realSubjectClass.getMethods();//实体类通过反射获取方法会获取到所有方法
Class<?> subjectClass = Subject.class;
Method[] subjectClassMethods = subjectClass.getMethods();
//接口通过反射获取方法只会获得接口定义的方法
System.out.println(realSubjectClass.getInterfaces()[0] == subjectClass);//true
//反射使对象的创建和操作都更加灵活了
// try {
// Constructor<?> constructor = realSubjectClass.getConstructor(String.class, int.class);
// RealSubject realSubject = (RealSubject) constructor.newInstance("Cat01",1);
// subjectClassMethods[0].invoke(realSubject, "test");
// System.out.println(realSubject);
// } catch (Exception e) {
// e.printStackTrace();
// }
}
}