使用Proxy和InvocationHandler创建动态代理
来源:互联网 发布:大阪 香港知乎 编辑:程序博客网 时间:2024/05/17 00:00
Proxy提供了用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类。如果在程序中为一个或多个接口动态的生成实现类,
就可以使用Proxy来创建动态代理类;如果需要为一个或多个接口动态地创建实例,也可以使用Proxy来创建动态代理实例。
Proxy提供了如下两个方法来动态创建代理类和动态代理实例。
(1) static Class<?> getProxyClass(ClassLoder loader, Class<?>...interfaces):创建一个动态代理类多对应的Class对象,该代理类实现将实现
interfaces所指定的多个接口。第一个ClassLoader参数指定生成动态代理类的类加载器。
(2) static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h):直接创建一个动态代理对象,该代
理对象对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会替换成执行InvocationHandler对象的invoke方法。
实际上,即使采用第一个方法生成动态代理类之后,如果程序需要通过该代理类来创建对象,依然需要传入一个Invocationhandler对象。也就
是说,系统生成的每个代理对象都有一个与之关联的Invocationhandler对象。例如下面的代码:
// 创建一个InvocationHandler对象,其中MyInvocationHandler是实现InvocationHandler接口的类InvocationHandler handler = new MyInvocationHandler();// 使用Proxy生成一个动态代理类proxyClassClass proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[]{Foo.class});// 获取proxyClass类中带有一个InvocationHandler参数的构造器Constructor ctor = proxyClass.getConstructor(new Class[]{Invocationhandler.class});// 调用ctor的newInstance方法来创建动态实例Foo f = (Foo) ctor.newInstance(new Object[]{Handler});
下面程序示范了使用Proxy和InvocationHandler来生成动态代理对象。其目的是:对需要代理的对象的每个方法的开始和结束打印一行日志
信息:
ArithmeticCalculatorloggingImpl.java:
package com.yu.spring.aop.helloworld;public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int i, int j) { int result = i + j; return result; } @Override public int sub(int i, int j) { int result = i - j; return result; } @Override public int mul(int i, int j) { int result = i * j; return result; } @Override public int div(int i, int j) { int result = i / j; return result; }}
ArithmeticCalculatorLoggingProxy.java:
package com.yu.spring.aop.helloworld;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Arrays;public class ArithmeticCalculatorLoggingProxy { // 要代理的对象 private ArithmeticCalculator target; public ArithmeticCalculatorLoggingProxy(ArithmeticCalculator target) { this.target = target; } public ArithmeticCalculator getLoggingProxy(){ ArithmeticCalculator proxy = null; // 代理对象由哪一个类加载器负责加载 ClassLoader loader = target.getClass().getClassLoader(); // 代理对象的类型,即其中有哪些方法 Class[] interfaces = new Class[]{ArithmeticCalculator.class}; // 当调用代理对象其中的方法时,该执行的代码 InvocationHandler h = new InvocationHandler(){ /** * 执行动态代理对象的所有方法时,都会替换成执行如下的invoke方法,其中: * proxy:正在返回的代理对象,一般情况下,在invoke方法中都不使用该对象 * method:正在被调用的方法 * args:调用方法时,传入的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); // 日志 System.out.println("the method " + methodName + " begins with " + Arrays.asList(args)); // 执行方法 Object result = method.invoke(target, args); // 日志 System.out.println("The method " + methodName + " ends with " + Arrays.asList(args)); return result; } }; proxy =(ArithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h); return proxy; }}
测试类Main.java:
package com.yu.spring.aop.helloworld;public class Main { public static void main(String[] args) {// ArithmeticCalculator ac = null;// ac = new ArithmeticCalculatorImpl(); ArithmeticCalculator target = new ArithmeticCalculatorImpl(); ArithmeticCalculator proxy = new ArithmeticCalculatorLoggingProxy(target).getLoggingProxy(); int result = proxy.add(1, 2); System.out.println("-->" + result); result = proxy.sub(4, 1); System.out.println("-->" + result); result = proxy.mul(2, 3); System.out.println("-->" + result); result = proxy.div(7, 3); System.out.println("-->" + result); }
测试结果:
0 0
- 使用Proxy和InvocationHandler创建动态代理
- 使用反射生成JDK动态代理---使用Proxy和InvocationHandler创建动态代理
- 使用java.lang.reflect.Proxy和InvocationHandler创建动态代理(仅代理接口)
- JDK使用InvocationHandler和Proxy实现动态代理
- 动态代理 Proxy InvocationHandler
- 动态代理proxy ,InvocationHandler
- 动态代理 Proxy InvocationHandler
- java动态代理-InvocationHandler Proxy
- Java动态代理InvocationHandler+Proxy
- InvocationHandler,proxy之动态代理
- 动态代理 Proxy InvocationHandler学习
- 动态代理 Proxy, InvocationHandler 用法
- JDK动态代理proxy,InvocationHandler
- 动态代理 Proxy InvocationHandler学习
- 使用JDK中的InvocationHandler、Proxy实现动态代理
- 动态代理两个类Proxy和InvocationHandler的模拟实现
- java动态代理实现Proxy和InvocationHandler cglib
- InvocationHandler和Proxy(Class)的动态代理机制详解
- Hadoop分布式文件系统——导入和导出数据
- 【javascript】详解location.href几种用法的区别
- RESUME
- GCD
- Struts2练习--基于注解方式Action配置
- 使用Proxy和InvocationHandler创建动态代理
- 桥接模式
- 三体-读书笔记
- 不错的博客和工具网站
- 广播接收者实现短信拦截器
- linux网络编程之socket(三):最简单的回射客户/服务器程序、time_wait 状态
- 抽象工厂模式
- 全国省市县无刷新多级联动菜单
- orm2 中文文档 4.1 hasOne(多对一关系)