当前位置: 移动技术网 > IT编程>开发语言>Java > java实现动态代理方法浅析

java实现动态代理方法浅析

2019年07月22日  | 移动技术网IT编程  | 我要评论

一些java项目中在mybatis与spring整合中有mapperscannerconfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类。

有鉴于此,本文浅析了java的动态代理。

本文使用动态代理模拟处理事务的拦截器。

接口:

public interface userservice {
  public void adduser();
  public void removeuser();
  public void searchuser();
}

实现类:

public class userserviceimpl implements userservice {
  public void adduser() {
    system.out.println("add user");
  }
  public void removeuser() {
    system.out.println("remove user");
  }
  public void searchuser() {
    system.out.println("search user");
  }
}

java动态代理的实现有2种方式

1.jdk自带的动态代理

使用jdk自带的动态代理需要了解invocationhandler接口和proxy类,他们都是在java.lang.reflect包下。

invocationhandler介绍:

invocationhandler是代理实例的调用处理程序实现的接口。

每个代理实例都具有一个关联的invocationhandler。对代理实例调用方法时,这个方法会调用invocationhandler的invoke方法。

proxy介绍:

proxy 提供静态方法用于创建动态代理类和实例。

实例(模拟aop处理事务):

public class transactioninterceptor implements invocationhandler {

  private object target;

  public void settarget(object target) {
    this.target = target;
  }
  
  @override
  public object invoke(object proxy, method method, object[] args) throws throwable {
    system.out.println("start transaction");
    method.invoke(target, args);
    system.out.println("end transaction");
    return null;
  }

}

测试代码:

public class testdynamicproxy {

  @test
  public void testjdk() {
    transactioninterceptor transactioninterceptor = new transactioninterceptor();
    userservice userservice = new userserviceimpl();
    transactioninterceptor.settarget(userservice);
    userservice userserviceproxy =
        (userservice) proxy.newproxyinstance(
            userservice.getclass().getclassloader(),
            userservice.getclass().getinterfaces(),
            transactioninterceptor);
    userserviceproxy.adduser();
  }

}

测试结果:

start transaction
add user
end transaction

很明显,我们通过userserviceproxy这个代理类进行方法调用的时候,会在方法调用前后进行事务的开启和关闭。

2. 第三方库cglib

cglib是一个功能强大的,高性能、高质量的代码生成库,用于在运行期扩展java类和实现java接口。

它与jdk的动态代理的之间最大的区别就是:

jdk动态代理是针对接口的,而cglib是针对类来实现代理的,cglib的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

实例代码如下:

public class userservicecallback implements methodinterceptor {

  @override
  public object intercept(object o, method method, object[] args, methodproxy methodproxy) throws throwable {
    system.out.println("start transaction by cglib");
    methodproxy.invokesuper(o, args);
    system.out.println("end transaction by cglib");
    return null;
  }

}

测试代码:

public class testdynamicproxy {

  @test
  public void testcglib() {
    enhancer enhancer = new enhancer();
    enhancer.setsuperclass(userserviceimpl.class);
    enhancer.setcallback(new userservicecallback());
    userserviceimpl proxy = (userserviceimpl)enhancer.create();
    proxy.adduser();
  }

}

测试结果:

start transaction by cglib
add user
end transaction by cglib

感兴趣的读者可以实际测试一下本文实例,相信会有很大的收获。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网