JDK的动态(静态)代理机制(转载并整理修改)
来源:互联网 发布:内蒙古大数据产业 编辑:程序博客网 时间:2024/06/18 12:35
动态代理代码如下:
package proxy.myproxy.dynamicProxy;public interface UserDao { void save();}
package proxy.myproxy.dynamicProxy;public class UserDaoImpl implements UserDao { public void save() { System.out.println("UserDao save()"); }}
package proxy.myproxy.dynamicProxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class InvocationHandlerImpl implements InvocationHandler { //表明被代理对象 private Object target; public InvocationHandlerImpl(Object target){ this.target = target; } public Object invoke(Object proxy, Method method, Object[] args)//args是那个你执行的那个方法的参数 throws Throwable { System.out.println(proxy.getClass());//这里输出:class $Proxy0,可以看出proxy是什么 System.out.println(target.getClass());//这里输出:class proxy.myproxy.dynamicProxy.UserDaoImpl,可以看出target是什么 System.out.println("开始记录日志"); //调用被代理对象的对应方法 Object obj = method.invoke(target, args);//obj是方法执行完之后的返回值 System.out.println("结束记录日志"); return obj; }}
package proxy.myproxy.dynamicProxy;import java.lang.reflect.Proxy;public class Test { public static void main(String[] args) { UserDao userDao = new UserDaoImpl(); //产生代理对象,采用组合方式,因此代理对象与被代理对象须实现相同接口 UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandlerImpl(userDao)); //方法调用时都会将自身传递给InvocationHandler,顺带将代理对象与参数一并传过来, //使用invoke(Object proxy, Method method, Object[] args)方法 userDaoProxy.save(); }}
解释:
1. Proxy即动态代理类;
2. Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用;
它有三个参数:
ClassLoader loader ----指定被代理对象的类加载器,我们产生的代理对象中实际上包含了被代理对象
Class[] Interfaces ----指定被代理对象所以事项的接口
InvocationHandler h ----指定需要调用的InvocationHandler对象
3. 实现InVocationHandler接口的InvocationHandlerImpl对象
这个对象的invoke()方法就是Proxy这个动态代理类所代理的接口类的抽象方法的真实实现;
它有三个参数:
Object proxy -----代理类对象
Method method -----被代理对象的方法(这里不是接口的抽象方法了,是具体的实现类中的方法)
Object[] args -----该方法的参数数组
userDaoProxy.save();的实现可以这样理解:
/*class $Proxy0 * { * //上边的方法写是无参的,这个是有参 * save(User u){ * Method m = UserDAO.getclass.getmethod * li.invoke(this,m,u); * } * } */
JDK中具体的动态代理类是怎么产生的呢?
1.产生代理类$Proxy0类
执行了Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
将产生$Proxy0类,它继承Proxy对象,并根据第二个参数,实现了被代理类的所有接口,自然就可以生成接口要实现的所有方法了(这时候会重写hashcode,toString和equals三个方法),但是还没有具体的实现体;
2. 将代理类$Proxy0类加载到JVM中
这时候是根据Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第一个参数----就是被代理类的类加载器,把当前的代理类加载到JVM中
3. 创建代理类$Proxy0类的对象
调用的$Proxy0类的$Proxy0(InvocationHandler)构造函数,生成$Proxy0类的对象
参数就是Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)它的第三个参数
这个参数就是我们自己实现的InvocationHandler对象,我们知道InvocationHandler对象中组合加入了代理类代理的接口类的实现类;所以,$Proxy0对象调用所有要实现的接口的方法,都会调用InvocationHandler对象的invoke()方法实现;
4. 生成代理类的class byte
动态代理生成的都是二进制class字节码
静态代理代码如下:
package proxy.myproxy.staticProxy;public interface UserDao { void save();}
package proxy.myproxy.staticProxy;public class UserDaoImpl implements UserDao { public void save() { System.out.println("UserDao save()"); }}
package proxy.myproxy.staticProxy;public class UserDaoImplProxy implements UserDao { private UserDao userDao = new UserDaoImpl();//合成 也可以传个引用过来 public void save() { System.out.println("开始记录日志。。。"); userDao.save(); System.out.println("结束记录日志。。。。"); }}
package proxy.myproxy.staticProxy;public class Test { public static void main(String[] args) { UserDao userDao = new UserDaoImplProxy(); System.out.println("test123"); userDao.save(); }}
参考:http://www.cnblogs.com/fuckqq/archive/2012/10/04/jdk_proxy.html
&& http://hi.baidu.com/wolf55/item/7f39971451f9ed4ee75e068f
- JDK的动态(静态)代理机制(转载并整理修改)
- JDK的动态代理机制
- JDK的动态代理机制
- JDK的动态代理机制
- JDK的动态代理机制
- JDK的动态代理机制
- JDK的动态代理机制
- JDK的动态代理机制
- JDK的动态代理机制
- JDK动态代理机制
- JDK动态代理机制
- JDK动态代理机制
- [java] JDK 的动态代理机制
- 黑马程序员 jdk的静态代理和动态代理
- JAVA的代理模式(静态代理、JDK动态代理、cglib动态代理)
- jdk动态代理(转载)
- JAVA的静态代理与动态代理比较--转载
- JAVA的静态代理与动态代理比较--转载
- 并发下的对象的共享简述
- 利用log4j将记录日志写入数据库
- JAVA位运算符回顾
- NSOperation/NSOperationQueue small demo
- python核心编程第九章习题答案(1)
- JDK的动态(静态)代理机制(转载并整理修改)
- @SuppressWarnings的使用、作用、用法
- (Oracle功能篇) Oracle 数据库连接池
- hadoop在ubuntu下的安装配置
- Android设置系统时间和时区
- 整合strust2和spring的关键点(为action注入service)
- Console命令详解,让调试js代码变得更简单
- BroadcastReceiver随笔(动态注册和静态注册)
- 【xtku】独立旅行xp主题_8.6