java实现动态代理方法浅析

 更新时间:2014年08月18日 12:00:29   投稿:shichen2014  
这篇文章主要介绍了java实现动态代理方法浅析,很实用的功能,需要的朋友可以参考下

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

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

相关文章

  • IDEA创建自定义模板图文教程

    IDEA创建自定义模板图文教程

    我们每次在使用IntelliJ IDEA 时总会有一些文件是一直被创建的,今天我们就来学习一下IntelliJ IDEA 的自定义模板功能,文中有详细的图文介绍,需要的朋友可以参考下
    2021-05-05
  • java编写简易贪吃蛇游戏

    java编写简易贪吃蛇游戏

    这篇文章主要为大家详细介绍了java编写简易贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • 基于Java注解(Annotation)的自定义注解入门介绍

    基于Java注解(Annotation)的自定义注解入门介绍

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法
    2013-04-04
  • Java面试最容易被刷的重难点之锁的使用策略

    Java面试最容易被刷的重难点之锁的使用策略

    锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂。因为锁(以及其它更高级的线程同步机制)是由synchronized同步块的方式实现的,所以我们还不能完全摆脱synchronized关键字
    2021-10-10
  • Mybatis-plus自动填充不生效或自动填充数据为null原因及解决方案

    Mybatis-plus自动填充不生效或自动填充数据为null原因及解决方案

    本文主要介绍了Mybatis-plus自动填充不生效或自动填充数据为null原因及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • jxls2.4.5如何动态导出excel表头与数据

    jxls2.4.5如何动态导出excel表头与数据

    这篇文章主要介绍了jxls2.4.5如何动态导出excel表头与数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java concurrency之AtomicReference原子类_动力节点Java学院整理

    Java concurrency之AtomicReference原子类_动力节点Java学院整理

    AtomicReference是作用是对"对象"进行原子操作。这篇文章主要介绍了Java concurrency之AtomicReference原子类,需要的朋友可以参考下
    2017-06-06
  • Java代码实现随机生成汉字的方法

    Java代码实现随机生成汉字的方法

    今天小编就为大家分享一篇关于Java代码实现随机生成汉字的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • java多线程之Future和FutureTask使用实例

    java多线程之Future和FutureTask使用实例

    这篇文章主要介绍了java多线程之Future和FutureTask使用实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 用Java实现简单计算器功能

    用Java实现简单计算器功能

    这篇文章主要为大家详细介绍了用Java实现简单计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07

最新评论