面试题答案
一键面试动态代理实现原理
- 代理模式基础:代理模式是一种设计模式,其中代理对象代表目标对象进行操作。在动态代理中,代理对象是在运行时动态生成的,而不是像静态代理那样在编译期就确定。
- InvocationHandler接口:动态代理通过
InvocationHandler
接口来处理方法调用。当通过代理对象调用方法时,实际会调用InvocationHandler
的invoke
方法。 - Proxy类:Java的
Proxy
类负责生成动态代理类和代理对象。通过Proxy.newProxyInstance
方法可以创建代理对象,该方法接收三个参数:类加载器、目标对象实现的接口数组、InvocationHandler
实例。
反射在处理方法调用中的具体过程
- 获取方法对象:在
InvocationHandler
的invoke
方法中,通过反射获取目标对象中被调用方法的Method
对象。例如,假设目标对象为target
,方法名为methodName
,可以使用target.getClass().getMethod(methodName, parameterTypes)
来获取Method
对象,其中parameterTypes
是方法参数的类型数组。 - 调用方法:获取到
Method
对象后,使用反射的Method.invoke
方法来调用目标对象的实际方法。invoke
方法的第一个参数为目标对象实例,后续参数为实际方法调用所需的参数。即method.invoke(target, args)
,其中args
是实际方法调用的参数数组。
代码示例
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义接口
interface HelloService {
void sayHello();
}
// 实现接口的目标类
class HelloServiceImpl implements HelloService {
@Override
public void sayHello() {
System.out.println("Hello, World!");
}
}
// 定义InvocationHandler实现类
class HelloServiceInvocationHandler implements InvocationHandler {
private Object target;
public HelloServiceInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method invocation");
Object result = method.invoke(target, args);
System.out.println("After method invocation");
return result;
}
}
// 测试类
public class DynamicProxyExample {
public static void main(String[] args) {
HelloService target = new HelloServiceImpl();
HelloServiceInvocationHandler handler = new HelloServiceInvocationHandler(target);
HelloService proxy = (HelloService) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler);
proxy.sayHello();
}
}
在上述代码中:
- 定义了
HelloService
接口和HelloServiceImpl
实现类。 HelloServiceInvocationHandler
实现了InvocationHandler
接口,在invoke
方法中通过反射调用目标对象的方法,并在方法调用前后打印日志。- 在
main
方法中,通过Proxy.newProxyInstance
创建代理对象,并调用代理对象的sayHello
方法,实际调用会经过InvocationHandler
的invoke
方法处理。