代理类热重载
代理类热重载非常重要,因为 Spring 和 MyBatisPlus 等都是通过代理类对代码进行增强。
JDK
定义接口
java
public interface UserService {
void addUser(String name);
}
定义实现类
java
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name) {
System.out.println("Add user: " + name);
printName(name);
}
public void printName(String name) {
System.out.println("printName: " + name);
}
}
定义 InvocationHandler
java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class UserServiceInvocationHandler implements InvocationHandler {
private final Object target;
public UserServiceInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("addUser")) {
System.out.println("Before method: " + method.getName());
printName("Before", method.getName());
Object result = method.invoke(target, args);
System.out.println("After method: " + method.getName());
printName("After", method.getName());
return result;
} else {
return method.invoke(target, args);
}
}
private void printName(String hook, String name) {
System.out.println(hook + " printName :" + name);
}
}
使用 Proxy 创建代理对象
java
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) throws InterruptedException {
// 创建目标对象
UserService target = new UserServiceImpl();
// 创建 InvocationHandler
UserServiceInvocationHandler handler = new UserServiceInvocationHandler(target);
// 创建代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler
);
while (true) {
Thread.sleep(10000);
// 调用代理对象的方法
proxy.addUser("DebugTools");
}
}
}
打印执行
text
# 热重载之前
Before method: addUser
Add user: DebugTools
After method: addUser
# 热重载之后
Before printName: addUser
printName: DebugTools
After printName: addUser
Cglib
创建代理对象
java
public class UserService {
public void addUser(String name) {
System.out.println("Add user: " + name);
printName(name);
}
public void printName(String name) {
System.out.println("printName: " + name);
}
}
编写方法拦截器
java
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class UserServiceInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (method.getName().equals("addUser")) {
System.out.println("Before method: " + method.getName());
printName("Before", method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method: " + method.getName());
printName("After", method.getName());
return result;
} else {
return proxy.invokeSuper(obj, args);
}
}
private void printName(String hook, String name) {
System.out.println(hook + " printName :" + name);
}
}
使用 Enhancer 动态生成代理类:
java
import net.sf.cglib.proxy.Enhancer;
public class ProxyTest {
public static void main(String[] args) throws InterruptedException {
// 创建 Enhancer 对象
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new UserServiceInterceptor());
UserService proxy = (UserService) enhancer.create();
while (true) {
Thread.sleep(1000);
// 调用代理对象的方法
proxy.addUser("DebugTools");
}
}
}
打印执行
text
# 热重载之前
Before method: addUser
Add user: DebugTools
After method: addUser
# 热重载之后
Before printName: addUser
printName: DebugTools
After printName: addUser