[关闭]
@cxm-2016 2016-12-29T13:56:33.000000Z 字数 1924 阅读 2161

Java:动态代理

Java

版本:1
作者:陈小默
声明:禁止商业,禁止转载


Java中实现一个动态代理通常有两种方式:

jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。

JDK动态代理

声明接口定义实现

  1. interface User {
  2. fun getName(): String
  3. fun getAge(): Int
  4. }
  5. class UserImpl(private val name: String,
  6. private val age: Int) : User {
  7. override fun getName(): String {
  8. return name
  9. }
  10. override fun getAge(): Int {
  11. return age
  12. }
  13. }

实现动态代理

  1. class UserProxy(private val user: User) : InvocationHandler {
  2. fun proxy(): User {
  3. return Proxy.newProxyInstance(user.javaClass.classLoader,
  4. user.javaClass.interfaces,
  5. this) as User
  6. }
  7. override fun invoke(proxy: Any?, method: Method, args: Array<out Any>?): Any {
  8. return when (method.name) {
  9. "getName" -> {
  10. val name = method.invoke(user)
  11. "$name Chou"
  12. }
  13. "getAge" -> {
  14. val age = method.invoke(user) as Int
  15. age + 3
  16. }
  17. else -> {
  18. method.invoke(user, args)
  19. }
  20. }
  21. }
  22. }

从实现中可以看出Java动态代理的实现方式是基于反射的实现,将反射出的方法对象和参数取出,然后交给InvocationHandlerinvoke方法自行实现。这里我们将对象更改为自己的User实例,修改调用结果并且返回。

  1. fun main(args: Array<String>) {
  2. val user = UserProxy(UserImpl("Jack", 22)).proxy()
  3. println(user.getName())
  4. println(user.getAge())
  5. }

CGLIB动态代理实现

CGLIB是一个强大的高性能的代码生成包。

  1. 它广泛的被许多AOP的框架使用,例如:spring AOP和dynaop,为他们提供方法的interception(拦截);
  2. hibernate使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的);
  3. EasyMock和jMock是通过使用模仿(moke)对象来测试Java代码的包。

CGLIB在实现动态代理的过程中要求被代理的类能够被继承,也就是说不能够是被final修饰的。

实现代理对象

  1. class UserProxy() : MethodInterceptor {
  2. fun <T> proxy(clazz: Class<T>, argTypes: Array<out Class<out Any>>? = null, args: Array<out Any>? = null): T {
  3. val enhancer = Enhancer()
  4. enhancer.setSuperclass(clazz)
  5. enhancer.setCallback(this)
  6. return enhancer.create(argTypes, args) as T
  7. }
  8. override fun intercept(proxy: Any, method: Method, args: Array<out Any>?, methodProxy: MethodProxy): Any {
  9. return when (method.name) {
  10. "getName" -> {
  11. val name = methodProxy.invokeSuper(proxy, args)
  12. "$name Chou"
  13. }
  14. "getAge" -> {
  15. val age = methodProxy.invokeSuper(proxy, args) as Int
  16. age + 10
  17. }
  18. else -> {
  19. methodProxy.invokeSuper(proxy, args)
  20. }
  21. }
  22. }
  23. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注