静态代理
public class UserControllerProxy implements IUserController {
private MetricsCollector metricsCollector;
private UserController userController;
public UserControllerProxy(UserController userController) {
this.userController = userController;
this.metricsCollector = new MetricsCollector();
}
@Override
public void login(String telephone, String password) {
long startTimestamp = System.currentTimeMillis();
// 委托
UserVo userVo = userController.login(telephone, password);
long endTimeStamp = System.currentTimeMillis();
long responseTime = endTimeStamp - startTimestamp;
RequestInfo requestInfo = new RequestInfo("login", responseTime, startTimestamp);
metricsCollector.recordRequest(requestInfo);
}
@Override
public void register(String telephone, String password) {
long startTimestamp = System.currentTimeMillis();
// 委托
UserVo userVo = userController.register(telephone, password);
long endTimeStamp = System.currentTimeMillis();
long responseTime = endTimeStamp - startTimestamp;
RequestInfo requestInfo = new RequestInfo("register", responseTime, startTimestamp);
metricsCollector.recordRequest(requestInfo);
}
}
动态代理
就是我们不事先为每个原始类编写代理类,而是在运行的时候,动态地创建原始类对应的代理类,然后在系统中用代理类替换掉原始类。
JDK动态代理
定义一个接口
package com.wqq.example.demo.test;
public interface ProductService {
void addProduct(String name);
}
实现类
package com.wqq.example.demo.test;
/**
* @ClassName ProductServiceImpl
* @Description todo
* @Author wenqiqi090
* @Date 2021/12/30 7:21 下午
*/
public class ProductServiceImpl implements ProductService{
@Override
public void addProduct(String name) {
System.out.println("正在添加商品");
}
}
InvocationHandler
`invoke()` 方法有下面三个参数:
1. **proxy** :动态生成的代理类
2. **method** : 与代理类对象调用的方法相对应
3. **args** : 当前 method 方法的参数
package com.wqq.example.demo.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @ClassName JdkInvocationHandler
* @Description todo
* @Author wenqiqi090
* @Date 2021/12/30 7:19 下午
*/
public class JdkInvocationHandler implements InvocationHandler {
private ProductService target;
public Object getInstance(ProductService target) {
this.target = target;
Class clazz = this.target.getClass();
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// args==11
System.out.println("begin");
Object returnValue = method.invoke(target, args);
System.out.println(returnValue);
System.out.println("end");
return returnValue;
}
}
Test类
package com.wqq.example.demo.test;
import sun.misc.ProxyGenerator;
import java.io.FileOutputStream;
/**
* @ClassName JdkTest
* @Description todo
* @Author wenqiqi090
* @Date 2021/12/30 7:29 下午
*/
public class JdkTest {
public static void main(String[] args) throws Exception {
ProductService productService = new ProductServiceImpl();
ProductService productServiceProxy = (ProductService) new JdkInvocationHandler().getInstance(productService);
productServiceProxy.addProduct("phone");
// 这里我们将jdk生成的代理类输出了出来,方便后面分析使用
byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{productService.getClass()});
FileOutputStream os = new FileOutputStream("Proxy0.class");
os.write(bytes);
os.close();
}
}
调用步骤
- begin
- 正在添加商品
- null
- end
生成的代理类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import com.wqq.example.demo.test.ProductServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements ProductServiceImpl {
private static Method m1;
private static Method m8;
private static Method m2;
private static Method m3;
private static Method m5;
private static Method m4;
private static Method m7;
private static Method m9;
private static Method m0;
private static Method m6;
public $Proxy0(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 notify() throws {
try {
super.h.invoke(this, m8, (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 addProduct(String var1) throws {
try {
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void wait(long var1) throws InterruptedException {
try {
super.h.invoke(this, m5, new Object[]{var1});
} catch (RuntimeException | InterruptedException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final void wait(long var1, int var3) throws InterruptedException {
try {
super.h.invoke(this, m4, new Object[]{var1, var3});
} catch (RuntimeException | InterruptedException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw new UndeclaredThrowableException(var6);
}
}
public final Class getClass() throws {
try {
return (Class)super.h.invoke(this, m7, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void notifyAll() throws {
try {
super.h.invoke(this, m9, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
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);
}
}
public final void wait() throws InterruptedException {
try {
super.h.invoke(this, m6, (Object[])null);
} catch (RuntimeException | InterruptedException | 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"));
m8 = Class.forName("com.wqq.example.demo.test.ProductServiceImpl").getMethod("notify");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.wqq.example.demo.test.ProductServiceImpl").getMethod("addProduct", Class.forName("java.lang.String"));
m5 = Class.forName("com.wqq.example.demo.test.ProductServiceImpl").getMethod("wait", Long.TYPE);
m4 = Class.forName("com.wqq.example.demo.test.ProductServiceImpl").getMethod("wait", Long.TYPE, Integer.TYPE);
m7 = Class.forName("com.wqq.example.demo.test.ProductServiceImpl").getMethod("getClass");
m9 = Class.forName("com.wqq.example.demo.test.ProductServiceImpl").getMethod("notifyAll");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m6 = Class.forName("com.wqq.example.demo.test.ProductServiceImpl").getMethod("wait");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
public final void addProduct(String var1) throws {
try {
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
其中h是 JdkInvocationHandler
源码分析
获取代理类
动态生成class文件放进jvm内存里
通过反射生成代理类