关于Java动态代理的解析

发布时间:2016-12-14 00:00:00 编辑:嘉辉 手机版

  动态代理类是位于Java.lang.reflect包下的Interface InvocationHandler。下面小编准备了关于Java动态代理的解析,提供给大家参考!

  众所周知,JDK的动态代理模式必须实现接口。

  以下面的源码为例:

  接口一:

  public interface ActionInterface {

  void doSelf(String str);

  String getType();

  }

  接口二:

  public interface InterruupIntf {

  void interrup();

  }

  实现类:

  public class MyselfImpl implements ActionInterface, InterruupIntf {

  public String getType() {

  String type = "公用部门";

  System.out.println(type);

  return type;

  }

  public void doSelf(String str) {

  System.out.println("业务实现类: " + str + " !");

  }

  public void interrup() {

  System.out.println("发呆三分钟!");

  }

  }

  动态代理需要反射,

  * 必须要实现InvocationHandler接口

  * 能够对所有的方法进行代理

  public class MyInvocationHandler implements InvocationHandler {

  private Object obj;

  /**

  * 通过构造方法来设置被代理的对象

  * @param obj

  */

  public MyInvocationHandler(Object obj) {

  this.obj = obj;

  }

  /**

  * 动态代理需要反射

  *

  */

  public Object invoke(Object proxy, Method method, Object[] args)

  throws Throwable {

  System.out.println("+++++++++++调用业务方法之前做其他事情");

  Object returnObject = method.invoke(obj, args);

  System.out.println("+++++++++++调用业务方法之前做其他事情");

  return returnObject;

  }

  /**

  * 测试函数

  * 动态代理对所有的代理类都进行了拦截

  * @throws NoSuchMethodException

  * @throws InvocationTargetException

  * @throws IllegalAccessException

  * @throws InstantiationException

  * @throws SecurityException

  * @throws IllegalArgumentException

  */

  public static void main(String[] args) throws InterruptedException,

  IllegalArgumentException, SecurityException,

  InstantiationException, IllegalAccessException,

  InvocationTargetException, NoSuchMethodException {

  //实现业务逻辑的类

  MyselfImpl muSelf = new MyselfImpl();

  //JDK创建的动态逻辑类,调用上面的构造函数注入

  MyInvocationHandler myInvocation = new MyInvocationHandler(muSelf);

  /*

  Class proxyClass = Proxy.getProxyClass(

  MyselfImpl.class.getClassLoader(), MyselfImpl.class.getInterfaces());

  //建业务逻辑类的动态代理类

  Object proxy = proxyClass.getConstructor(

  new Class[] { InvocationHandler.class }).newInstance(

  new MyInvocationHandler(new MyselfImpl())); */

  //建业务逻辑类的动态代理类

  Object proxy = Proxy.newProxyInstance(MyselfImpl.class.getClassLoader(), MyselfImpl.class.getInterfaces(), myInvocation);

  //业务类自己调用运行代理对象

  ActionInterface testIntf = (ActionInterface) proxy;

  testIntf.doSelf("我要做业务了!");

  testIntf.getType();

  InterruupIntf intIntf = (InterruupIntf) proxy;

  intIntf.interrup();

  }

  }

  运行最后一个类的MAIN函数,控制台输出结果如下:

  +++++++++++调用业务方法之前做其他事情

  业务实现类: 我要做业务了! !

  +++++++++++调用业务方法之前做其他事情

  +++++++++++调用业务方法之前做其他事情

  公用部门

  +++++++++++调用业务方法之前做其他事情

  +++++++++++调用业务方法之前做其他事情

  发呆三分钟!

  +++++++++++调用业务方法之前做其他事情

  看到结果了。

  JDK的动态代理,对MyselfImpl所有方法都进行了拦截,在调用真正的业务类方法之前之后都插入了代码,这就是JDK的动态代理。其实SPRING的AOP思想的基本原理也是这个,但是它写的比较负责,而且比较优秀。

本文已影响863
+1
0