A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 程有愿 中级黑马   /  2012-9-13 08:56  /  1580 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

动态代理类中的 Proxy.getProxyClass的参数各代表什么意思

3 个回复

倒序浏览
Proxy.getProxyClas(指定类加载器,指定接口)
回复 使用道具 举报
  Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。




(2).Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。



Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。

Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。





       所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。(参见文献3)



    在使用动态代理类时,我们必须实现InvocationHandler接口,以第一节中的示例为例:



抽象角色(之前是抽象类,此处应改为接口):

回复 使用道具 举报

楼主,使用jdk对动态代理的支持,常用的方法是Proxy.newProxyInstance,它接受三个参数,第一个参数为被代理对象的类加载器,第二个参数为需要代理的接口,这些接口的所有方法都会被代理,第三个参数为建立的InvocationHandler的实例,InvocationHandler实例的invoke方法里放上你的里逻辑

现在就举个实际例子说明吧

由于Jdk提供的代理只能代理接口,所以首先我们建立一个被代理的接口还有他的实现,就用项目中的dao层演示

现在有个用户访问数据库的Userdao,里面有个保存用户的方法,接受一个名字

  1. public interface UserDao {
  2. void save(String username);
  3. }
  4. UserDao的实现类UserDaoImpl
  5. public class UserDaoImpl implements UserDao {
  6. @Override
  7. public void save(String username) {
  8.   System.out.println(username + "存进了数据库");  
  9. }
  10. }
  11. 现在想对UserDaoImpl记录日志,写一个处理类LogHandler实现InvocationHandler接口
  12. public class LogHandler implements InvocationHandler {
  13. //被代理的对象
  14. private Object target;
  15. @Override
  16. public Object invoke(Object proxy, Method method, Object[] args)
  17.    throws Throwable {
  18.   //对被代理对象target的对应方法进行调用,把代理类接受的参数传递进去
  19.   Object result = method.invoke(target, args);
  20.   System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "用户" + args[0] + "保存进数据库");
  21.   return result;
  22. }

  23. //接收被代理的对象
  24. public LogHandler(Object target) {
  25.   super();
  26.   this.target = target;
  27. }
  28. }
  29. 用于测试的有main的类  ProxyTest
  30. public class ProxyTest {
  31. public static void main(String[] args) {
  32.   //被代理的UserDaoImpl对象
  33.   UserDao ud = new UserDaoImpl();
  34.   //生成代理对象,转成UserDao引用使用,注意这里不能转为UserDaoImpl的引用,只能使用对应接口,
  35.   //这是由于接口可以规范方法
  36.   UserDao proxy = (UserDao)Proxy.newProxyInstance(
  37.        ud.getClass().getClassLoader()//加载生成代理类的加载器
  38.        , ud.getClass().getInterfaces()//需要代理的接口,这里为UserDao
  39.        , new LogHandler(ud));//日志处理类
  40.   //对代理对象调用save方法
  41.   proxy.save("黑马程序员");
  42. }
  43. }
复制代码
控制台打印:黑马程序员存进了数据库
2012-09-06 14:12:23用户黑马程序员保存进数据库怎么样,这样就为UserDaoImpl动态的增加了功能,楼主自己写几个dome,慢慢的弄清楚了,关于动态代理的知识楼主可以去看下张孝祥老师的Java高新技术,张老师讲的特别好,视频下载地址:http://www.itcast.cn/channel/video.shtml#java


回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马