面试题答案
一键面试原理
在Kotlin中利用反射实现动态代理来拦截和增强目标对象方法调用,其原理如下:
- 获取目标类的元数据:通过反射获取目标类的相关信息,如类对象、方法等。
- 创建代理类:动态生成一个代理类,该代理类实现与目标类相同的接口(如果目标类是接口实现类)或者继承目标类(如果目标类不是final的)。
- 方法拦截与增强:在代理类的方法实现中,通过反射调用目标对象的方法,并在调用前后加入自定义的逻辑,实现拦截和增强。
核心代码片段
假设目标类是一个接口的实现类:
import java.lang.reflect.Proxy
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
// 定义接口
interface TargetInterface {
fun targetMethod()
}
// 目标类实现接口
class TargetClass : TargetInterface {
override fun targetMethod() {
println("Target method is called.")
}
}
// 定义InvocationHandler
class MyInvocationHandler(private val target: TargetInterface) : InvocationHandler {
override fun invoke(proxy: Any, method: Method, args: Array<out Any>?): Any? {
// 方法调用前增强逻辑
println("Before method invocation")
val result = method.invoke(target, *args.orEmpty())
// 方法调用后增强逻辑
println("After method invocation")
return result
}
}
// 创建代理实例
fun createProxy(target: TargetInterface): TargetInterface {
return Proxy.newProxyInstance(
target.javaClass.classLoader,
target.javaClass.interfaces,
MyInvocationHandler(target)
) as TargetInterface
}
fun main() {
val target = TargetClass()
val proxy = createProxy(target)
proxy.targetMethod()
}
在上述代码中:
TargetInterface
定义了目标类实现的接口。TargetClass
是目标类,实现了TargetInterface
。MyInvocationHandler
实现了InvocationHandler
接口,在invoke
方法中实现了方法的拦截和增强逻辑。createProxy
方法通过Proxy.newProxyInstance
创建代理实例。- 在
main
函数中,创建目标对象和代理对象,并调用代理对象的方法,此时会触发拦截和增强逻辑。