动态代理模式--基本使用

?简介

Java动态代理机制的出现,使得Java程序员不需要手工编写代理类,只需要指定对应的接口及委托类对象,便能动态的获取代理类。代理类负责将所有方法的调用委托到实际对象反射执行,在委托中,代理类可以加入自定义功能的实现。

静态代理

1,简介

普通静态代理模式,目的就是其他对象为了控制某对象的访问,而提供代理对象间接实现。

2,代理模式UML

3,角色介绍

ISubject:主题角色,定义对象的具体行为。

RealSubject:真实对象,被代理对象,实现主题角色,定义出具体行为。

Proxy:代理对象,一般实现主题角色,并持有真实对象的引用,在内部操作真实对象。

4,具体实现

静态代理的实现较为简单。具体可参考我之前的博客:http://blog.csdn.net/mergades/article/details/42173893

JDK动态代理相关类

1,Java.lang.reflect.Proxy:该类主要提供静态方法用来创建代理对象。

  1. * {@code Proxy} provides static methods for creating dynamic proxy
  2. * classes and instances, and it is also the superclass of all
  3. * dynamic proxy classes created by those methods.

getInvocationHandler方法:用于指定代理对象关联的调用处理器InvocationHandler。

  1. public static InvocationHandler getInvocationHandler(Object proxy)
  2.        throws IllegalArgumentException

newProxyInstance:获取对应指定类加载器,以及接口的动态代理类对象。

  1. @CallerSensitive
  2.    public static Object newProxyInstance(ClassLoader loader,
  3.                                          Class<?>[] interfaces,
  4.                                          InvocationHandler h)
  5.        throws IllegalArgumentException

针对Proxy类,我们可以在它的Java doc文档中看到对应的描述:

-1,代理类最终都关联一个InvocationHandler接口,该接口用来处理针对代理类的所有方法调用。

-2,代理类必须是public,final而且不能为Abstract。因为是final的,所以不能再被继承。

-3,代理类必须是“$ProxyN” 的命名格式。因为代理类类部实现了缓存机制,所以并不是每次生成代理类对象都会是新的对象。针对同一组接口的连续调用,会从缓存获取代理对象。

-4,如果代理类实现了非公共接口,那么该接口必须与代理类出于相同的包中。接口数量不能超过65535。

2,java.lang.reflect.InvocationHandler:指定对应动态代理类的处理器。每次生成代理对象都必须指定该对象,可以参考proxy的newProxyInstance方法参数。

invoke方法:该方法负责集中处理针对动态代理类所有方法的调用。

  1. public Object invoke(Object proxy, Method method, Object[] args)
  2.        throws Throwable;
简单动态代理的实现

主题接口:

  1. package com.jing.proxy;
  2. /**
  3. * 主题接口
  4. *
  5. * @author jinglongjun
  6. *
  7. */
  8. public interface ISubject {
  9. void doSomething();
  10. }

真实对象:

  1. package com.jing.proxy;
  2. /**
  3. * 具体的被代理对象。
  4. *
  5. * @author jinglongjun
  6. *
  7. */
  8. public class HelloSubject implements ISubject {
  9. @Override
  10. public void doSomething() {
  11. System.out.println("HelloSubject: say hello to everyone!");
  12. }
  13. }

Handler对象:

  1. package com.jing.proxy;
  2. import java.lang.reflect.InvocationHandler;
  3. import java.lang.reflect.Method;
  4. /**
  5. * Handler对象
  6. *
  7. * @author jinglongjun
  8. *
  9. */
  10. public class SubHandler implements InvocationHandler {
  11. private Object obj;// 持有真实对象
  12. public SubHandler(Object obj) {
  13. this.obj = obj;
  14. }
  15. @Override
  16. public Object invoke(Object proxy, Method method, Object[] args)
  17. throws Throwable {
  18. Object result = method.invoke(obj, args);// 真实对象来执行具体的方法
  19. System.out.println("说完你好,说再见》》》bye-bye!");//加入自己操作
  20. return result;
  21. }
  22. }

具体使用:

  1. package com.jing.proxy;
  2. import java.lang.reflect.Proxy;
  3. public class Test {
  4. public static void main(String[] args) {
  5. HelloSubject helloSubject = new HelloSubject();
  6. ISubject sub = (ISubject) Proxy.newProxyInstance(helloSubject.getClass()
  7. .getClassLoader(), helloSubject.getClass().getInterfaces(),
  8. new SubHandler(helloSubject));
  9. sub.doSomething();
  10. }
  11. }

执行结果:

  1. HelloSubject: say hello to everyone!
  2. 说完你好,说再见》》》bye-bye!

个人觉得,代码的重点还是在生成代理对象的时候,是如何将真实对象,和对应代理对象的InvocationHandler相互组装,实现我们最终需要的结果。具体就需要分析JDK的源码来看了。

具体源码,我们稍后分析。

本文主要参考:http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-29 13:14:05

动态代理模式--基本使用的相关文章

动态代理模式

动态代理模式简介: 动态代理能够自动监听代理对象的方法,并且能够自动生成代理类的代码,这样就不需要我们自己去重写代理对象里的方法了,这样解决了代理类代码因业务庞大而庞大的问题,因为动态代理模式会在代码运行时根据代码来在内存中动态生成一个代理类自动重写代理对象[学Java,到凯哥学堂kaige123.com]的方法,然后这个动态代理类再调用处理类里的代码,处理类再调用到实际方法上去.而且我们可以选择性的监听代理对象的方法,有些不需监听的方法就可以在处理类中过滤掉.所以动态代理的优势就在于可以自动的

java 动态代理模式

一.相关类及其方法:java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxyInstance()返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序(详见api文档) java.lang.reflect.InvocationHandler,InvocationHandler 是代理实例的调用处理程序 实现的接口.invoke()在代理实例上处理方法调用并返回结果.在与方法关联的代理实例上调用方法时,将在调用处理程序

Java静态代理与动态代理模式的实现

前言:    在现实生活中,考虑以下的场景:小王打算要去租房,他相中了一个房子,准备去找房东洽谈相关事宜.但是房东他很忙,平时上班没时间,总没有时间见面,他也没办法.后来,房东想了一个办法,他找到了一个人代替自己和小王洽谈,房东本人不用出面,他只要把他的对房客的要求告诉他找的那个人,那个人和你商量就可以了,这样就可以完成租房这件事了.这种现实场景比比皆是,所呈现出来的其实就是代理模式的原型的一种.我们把焦点转向编程,你是否在编程中经常遇见这样一个问题,对于访问某个对象,我们希望给它的方法前加入一

关于装饰模式和动态代理模式

装饰模式和动态代理模式乍一看差不多,都是动态的增加行为,其实有各自的区别. 一.首先我们看一下装饰设计模式,其基本思想如下: 1.编写一个类,实现与被装饰类相同的接口.目的使他们有相同的行为 2.定义一个实例变量,引用被装饰对象.目的和原来的老对象进行交接 3.定义构造方法,把被装饰对象注入进来. 4.对于不需要改写的方法,调用被装饰对象的. 5.对于要改写的方法,改写即可. 废话不多说,举一个例子,模拟实现一个数据库连接池,在这里,我想重写close方法,以实现调用close方法之后不是关闭连

23种设计模式----------代理模式(三) 之 动态代理模式

(上一篇)种设计模式----------代理模式(二) 当然代理模式中,用的最广泛的,用的最多的是  动态代理模式. 动态代理:就是实现阶段不用关系代理是哪个,而在运行阶段指定具体哪个代理. 抽象接口的类图如下: --图来自设计模式之禅 所以动态代理模式要有一个InvocationHandler接口 和 GamePlayerIH实现类.其中 InvocationHandler是JD提供的动态代理接口,对被代理类的方法进行代理. 代码实现如下 抽象主题类或者接口: 1 package com.ye

Java-马士兵动态代理模式

Java-马士兵动态代理模式 模拟jdk的动态代理的实现原理, 这些东西没有必要写出来,写项目的时候用不上,主要是面试和理解原理: ? 有些工具可以直接生成二进制码,没有必要生成文件. 代理模式-聚合与继承方式比较 参考地址:http://www.cnblogs.com/shamgod/p/4591782.html ? 一.概述 1.目标:要在Tank的move()方法做时间代理及日志代理(可以设想以后还要增加很多代理处理),且代理间的顺序可活更换 2.思路: (1)聚合:代理类聚合了被代理类,

设计模式之动态代理模式

设计模式之动态代理模式 代理模式: Provide a surrogate or placeholder for another object to controlaccess to it(为其他对象提供一种代理以控制对这个对象的访问).使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象.创建开销 大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能. 代理模式相关内容详见本人之前文章:http://www.cnblogs.com/zh

Android开发中无处不在的设计模式——动态代理模式

继续更新设计模式系列,写这个模式的主要原因是最近看到了动态代理的代码. 先来回顾一下前5个模式: - Android开发中无处不在的设计模式--单例模式 - Android开发中无处不在的设计模式--Builder模式 - Android开发中无处不在的设计模式--观察者模式 - Android开发中无处不在的设计模式--原型模式 - Android开发中无处不在的设计模式--策略模式 动态代理模式在Java WEB中的应用简直是随处可见,尤其在Spring框架中大量的用到了动态代理:算是最重要

动态代理模式--源码分析

Proxy源码 1,成员变量 ?代理类的构造函数参数.默认每个代理类都具有一个invocationHandler的构造方法.(本文代码主要基于jdk 1.7) /** parameter types of a proxy class constructor */ private static final Class<?>[] constructorParams = { InvocationHandler.class }; ?缓存代理对象. private static final WeakCa

Android知识体系梳理笔记三:动态代理模式---插件加载机制学习笔记

静态代理模式 静态代理模式就是我们常说的代理设计模式,我们采用一个代理类调用原有的方法,且对产生的结果进行控制:举个例子:我们现在在玩一款网络游戏,需要打怪升级:太累就找个代理吧,一觉醒来就会发现我们已经当上CEO,迎娶白富美,天下第一了! 本来我们只能打怪,打怪-,但经过代理类增强,我们不仅可以打怪,还可以升级拿装备.就这样子了! 上代码: * 同一功能接口 public interface PlayNetGame { String beatMonster(); } 1 2 3 4 1 2 3