动态代理
来源:互联网 发布:手机淘宝同城在哪里找 编辑:程序博客网 时间:2024/06/05 08:20
java动态代理实际上是为对象提供一个代理,用以对真实对象的访问。代理类负责为委托类预处理消息,过滤并转发消息,以及消息被委托之后的操作。通过代理层这一中间层,有效的控制对于真实委托类对象的直接访问,同时可以实现自定义的控制策略。(实际上就是spring aop)。
在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。
每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
proxy:指代我们所代理的那个真实对象method:指代我们所要调用真实对象的某个方法的Method对象
args:指代的是调用真实对象的某个方法是接受的参数
Proxy这个类就是用来动态创建一个代理对象
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
loader:一个ClassLoader对象,定义了由那个ClassLoader对象来对生成的代理对象进行加载
interfaces:一个interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供一组接口给他,那么这个代理对象就宣称实现了该接口,这样我们就可以调用这组接口中的方法了
h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪个InvocationHandler。
例子:
public interface Subject{ public void rent(); public void hello(String str);}
public class RealSubject implements Subject{ @Override public void rent() { System.out.println("I want to rent my house"); } @Override public void hello(String str) { System.out.println("hello: " + str); }
下一步,我们就要定义一个动态代理类了,前面说个,每一个动态代理类都必须要实现 InvocationHandler 这个接口,因此我们这个动态代理类也不例外:
public class DynamicProxy implements InvocationHandler{ // 这个就是我们要代理的真实对象 private Object subject; // 构造方法,给我们要代理的真实对象赋初值 public DynamicProxy(Object subject) { this.subject = subject; } @Override public Object invoke(Object object, Method method, Object[] args) throws Throwable { // 在代理真实对象前我们可以添加一些自己的操作 System.out.println("before rent house"); System.out.println("Method:" + method); // 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用 method.invoke(subject, args); // 在代理真实对象后我们也可以添加一些自己的操作 System.out.println("after rent house"); return null; }}最后,来看看我们的Client类:
public class Client{ public static void main(String[] args) { // 我们要代理的真实对象 Subject realSubject = new RealSubject(); // 我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的 InvocationHandler handler = new DynamicProxy(realSubject); /* * 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数 * 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象 * 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了 * 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上 */ Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject .getClass().getInterfaces(), handler); System.out.println(subject.getClass().getName()); subject.rent(); subject.hello("world"); }}
- 代理-->静态代理&动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- 动态代理
- URAL1004 Sightseeing Trip(Folyd求最小环,打印路径)
- 【动态规划】【子序列模板】
- 在进行npm安装时发现node_modules不知道跑哪去了
- JS中navigator对象详解
- git 常用命令
- 动态代理
- Hdu 1241 Oil Deposits DFS算法
- 水平居中/按钮点击变色
- 简单基础树状数组求逆序数 POJ2299
- js实现点击按钮复制文本框中的内容
- opencv图像的深度及取值范围
- java数组的使用(四步,初学)
- JavaScript-数据类型转换实例
- Python 包