代理的作用
通过代理方式可以对目标方法进行扩展, 添加一些自定义的逻辑或返回特定的结果
静态代理
特点
- 根据 Java API 代理机制规定, 被代理类必须要实现某个接口
- 代理类也需要实现相同的接口
- 代理类持有被代理类, 代理类里实现的方法通过调用持有的被代理类的对应方法实现
示例
```kotlin /**- 接口 */ interface IHello { fun sayHello() }
/**
- 被代理类
*/
class HelloImp : IHello {
override fun sayHello() {
} }println(">>>>> helloImp: hello <<<<<")
/**
- 代理类
*/
class HelloProxy : IHello {
private val hello = HelloImp()
override fun sayHello() {
} }hello.sayHello()
/**
- 根据 Java API 代理机制规定, 被代理类必须要实现某个接口
- 动态代理类需要实现 InvocationHandler
关键点在于 InvocationHandler的 invoke方法
应用场景
Retrofit API
-
InvocationHandler
第一种方式
通过构造方法传递被代理对象
- 在 invoke 方法里 method.invoke(xxx, args)
示例
InvocationHandler实现类class ProxyHandlerImp(private val obj: Any) : InvocationHandler {
override fun invoke(proxy: Any?, method: Method?, args: Array?): Any? {
return method?.invoke(obj)
}
}
调用方式
val h: InvocationHandler = ProxyHandlerImp(HelloImp())
val hProxy: IHello = Proxy.newProxyInstance(IHello::class.java.classLoader, arrayOf(IHello::class.java), h) as IHello
hProxy.sayHello()
第一种方式优化
- 通过工厂类和单例管理创建被代理类
- 通过 method 里携带的接口类进行对比拿到对应的被代理类实例
- 通过拿到的被代理实例 return method?.invoke(被代理实例)
第二种方式
直接在 invoke 方法里操作
- 通过 method.getName 来区分方法
- 通过对不同的方法返回不同的值
示例
InvocationHandler实现类class ProxyHandler2 : InvocationHandler {
override fun invoke(proxy: Any?, method: Method?, args: Array?): Any? {
return when(method?.name) {
"sayHello" -> {
println(" >>>>>> sayHello <<<<<<")
}
"sayBye" -> {
println(" >>>>>> sayBye <<<<<<")
}
else -> {
println(" >>>>>> empty <<<<<<")
}
}
return null
}
}
调用方式
val h: InvocationHandler = ProxyHandlerImp()
val hProxy: IHello = Proxy.newProxyInstance(IHello::class.java.classLoader, arrayOf(IHello::class.java), h) as IHello
hProxy.sayHello()
参考链接
https://www.jianshu.com/p/9bcac608c714
https://medium.com/hashtech/dynamic-proxy-in-java-56fbfa92c596
https://www.jianshu.com/p/9e55174d4d27