JDK动态代理技术
1.首先要有接口
public interface UserService {
public void a(int x, int y);
public void b();
public void c();
}
2.该接口要有实现类(动态代理的目标类)
// 目标类
public class UserServiceTarget implements UserService {
@Time
public void a(int x, int y) {
System.out.println("a");
}
public void b() {
System.out.println("b");
}
public void c() {
System.out.println("c");
}
}
3 动态代理的原理
// dynamic 动态的
// proxy 代理
public class TestDynamicProxy {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 1. 生成了类的字节码
// 参数1 string 表示代理类的名字
// 参数2 class[] 表示代理类要实现的接口
// 返回的结果就是 代理类 的字节码
byte[] bytes = ProxyGenerator.generateProxyClass("UserServiceProxy2", new Class[]{UserService.class});
FileOutputStream out = new FileOutputStream("d:\\UserServiceProxy.class");
out.write(bytes);
out.close();
// 2. 执行类加载
// 类加载的最终结果体现为 Class 类对象, 要借助类加载器
ClassLoader cl = new ClassLoader() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
return defineClass(name, bytes, 0, bytes.length);
}
};
Class c = cl.loadClass("UserServiceProxy2"); // 进行类加载, 获得了 UserServiceProxy 类对象
// 3. 创建代理类实例对象
// 不能正常创建它的实例对象, new UserServiceProxy2();
// 获取代理类的构造方法
Constructor constructor = c.getConstructor(InvocationHandler.class);
UserServiceTarget target = new UserServiceTarget();
// 创建实例对象, 强制转换为它的接口类型
UserService proxy = (UserService)constructor.newInstance(new InvocationHandler() {
@Override
// method 就是 a , b, c 等方法对象
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入了 invoke");
long start = System.nanoTime();
// 方法.invoke(目标, 参数);
method.invoke(target, args);
long end = System.nanoTime();
System.out.println("花费了:" + (end - start));
return null;
}
});
// 4. 使用代理对象
proxy.b();
proxy.c();
proxy.a(10,20);
}
}
4 动态生成的类
public final class UserServiceProxy2 extends Proxy implements UserService {
private static Method m1;
private static Method m5;
private static Method m3;
private static Method m2;
private static Method m4;
private static Method m0;
public UserServiceProxy2(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void b() throws {
try {
super.h.invoke(this, m5, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void c() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void a(int var1, int var2) throws {
try {
super.h.invoke(this, m4, new Object[]{var1, var2});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m5 = Class.forName("service.UserService").getMethod("b");
m3 = Class.forName("service.UserService").getMethod("c");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m4 = Class.forName("service.UserService").getMethod("a", Integer.TYPE, Integer.TYPE);
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
5 简化使用动态代理
public class TestDyanmicProxy2 {
public static void main(String[] args) {
// 直接创建代理类的实例
// 1. 获取类加载器
ClassLoader cl = UserService.class.getClassLoader();
// 2. 规定代理类要实现的接口
Class[] interfaces = new Class[] {UserService.class};
// 3. 给一个 InvocationHandler 对象, 包含要执行的重复逻辑
UserServiceTarget target = new UserServiceTarget();
InvocationHandler h = new InvocationHandler() {
@Override
// method 就是 a , b, c 等方法对象
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入了 invoke");
long start = System.nanoTime();
// 方法.invoke(目标, 参数);
method.invoke(target, args);
long end = System.nanoTime();
System.out.println("花费了:" + (end - start));
return null;
}
};
UserService proxy = (UserService) Proxy.newProxyInstance(cl, interfaces, h);
proxy.b();
}
}