欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java实现动态代理方法浅析

程序员文章站 2024-02-28 10:00:10
一些java项目中在mybatis与spring整合中有mapperscannerconfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类。 有鉴于此,本...

一些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

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