浅析Java动态代理

倖福魔咒の 提交于 2020-04-05 20:47:45

Java的动态代理主要是指位于java.lang.reflect包下的Proxy类,在使用过程中会用到同一个包下的InvocationHandler接口。

1.Proxy类提供了个静态方法Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) ,用来生成代理对象:

loader是目标类的类加载器,interfaces是目标类实现的接口(并不一定是它实现的所有接口,用Class<?>[]类型表示就可以了),h是InvocationHandler类型的一个对象。

2.InvocationHandler接口提供类一个方法Object invoke(Object proxy,Method method,Object[] args) throws Throwable,用来调用目标方法并提供新的功能:

proxy是代理对象,method是目标方法,args是目标方法的参数列表。

所谓动态代理其实就是这样的一种对象:它是在程序运行时动态生成的对象,在生成它时你必须提供一组接口给它,然后该对象就宣称它实现了这些接口。你当然可以把该对象当作这些接口中的任何一个来用。当然,这其实就是一个代理对象,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

接口:

public interface StudentDao { 
  public void test1(); 
  public void test2(); 
  public void test3(); 
  public void test4(); 
}
​
public interface StudentDao2 { 
  public void t(); 
} 

目标类:

public class StudentDaoImpl implements StudentDao ,StudentDao2{ 
    //对接口方法的实现 
}
Handler:

public class MyInvocationHandler implements InvocationHandler { 
  private Object target; 
  private List<String> matchNames=null; //用来控制对目标类的那些方法做功能上的改变
  public MyInvocationHandler() { 
  } 
  public MyInvocationHandler(Object target) { 
    this.target = target; 
    matchNames=new ArrayList<String>(); 
    matchNames.add("test1"); 
    matchNames.add("test2"); 
    matchNames.add("test3");     
  } 
  @Override 
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    String methodName=method.getName(); 
    if(matchNames.contains(methodName)){ 
      System.out.println("========begin transaction========="); 
    } 
    Object ret = method.invoke(target, args); 
    if(matchNames.contains(methodName)){ 
      System.out.println("========end transaction=========="); 
    } 
    return ret; 
  } 
}

测试类:

 public static void main(String[] args) { 
    StudentDaoImpl dao=new StudentDaoImpl(); 
    MyInvocationHandler handler=new MyInvocationHandler(dao); 
    StudentDao proxy=(StudentDao)Proxy.newProxyInstance(
                                        dao.getClass().getClassLoader(),
                                        new Class<?>[]{StudentDao.class},
                                        handler); 
    proxy.test1(); 
    proxy.test2(); 
    proxy.test3(); 
    proxy.test4(); 
}

运行结果:

========begin transaction=========
==========目标方法:test1()============
========end transaction==========
========begin transaction=========
==========目标方法:test2()============
========end transaction==========
========begin transaction=========
==========目标方法:test3()============
========end transaction==========
==========目标方法:test4()============

原文链接: https://blog.51cto.com/yangfei520/245254 文源网络,仅供学习之用,如有侵权,联系删除。

我将优质的技术文章和经验总结都汇集在了我的公众号【Java圈子】里。

为方便大家学习,我整理了一套学习资料,涵盖Java虚拟机、spring框架、Java线程、数据结构、设计模式等等,免费提供给热爱Java的同学! 更有学习交流群,多交流问题才能更快进步~

file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!