• 概念

    王宝强有一个经纪人叫宋喆,这个经纪人很吊,可以代理王宝强做一系列的事情,与粉丝活动、王宝强的微博维护、安排王宝强的行程以及什么什么等等。如果王宝强一个人做岂不是累死。通过这个代理人为王宝强节省了不少。

    代理模式就是在不改变原有类的代码结构上为类拓展新的功能。

  • 类图:subject为一个抽象的目标接口,客户端梦想的接口,realSubject为原始类,proxy为代理对象

  

  • 静态代理
  1. //原类与代理类的公共接口
  2. public interface Subject {
  3. public void request();
  4. }
  5.  
  6. public class RealSubject implements Subject{
  7.  
  8. public void request() {
  9. System.out.println("王宝强拍电影");
  10. }
  11. }
  12.  
  13. public class Proxy implements Subject {
  14. private Subject realSubject;
  15.  
  16. public void setRealSubject(Subject realSubject) {
  17. this.realSubject = realSubject;
  18. }
  19.  
  20. public void request() {
  21. System.out.println("宋喆代替王宝强维护微博");
  22. realSubject.request();
  23. System.out.println("宋喆代替王宝强与粉丝互动");
  24. }
  25. }
  26.  
  27. public class Main {
  28. public static void main(String[] args) {
  29. Subject realSubject=new RealSubject();
  30. Proxy proxy=new Proxy();
  31. proxy.setRealSubject(realSubject);
  32. proxy.request();
  33. }
  34. }
  • 动态代理
  1. public interface Subject {
  2. public void request();
  3. }
  4.  
  5. public class RealSubject implements Subject {
  6. public void request() {
  7. System.out.println("王宝强拍电影");
  8. }
  9. }
  10.  
  11. public class ProxyMain {
  12. public static void main(String[] args) {
  13. final RealSubject realSubject=new RealSubject();
  14. Subject proxy=(Subject) Proxy.newProxyInstance(
  15. /**
  16. * ClassLoader 被代理类的加载器
  17. * Interfaces 代理对象与被代理对象公共接口
  18. * InvocationHandle 事件处理
  19. */
  20. realSubject.getClass().getClassLoader(),
  21. realSubject.getClass().getInterfaces(),
  22. new InvocationHandler() {
  23. public Object invoke(Object proxy, Method method, Object[] args)
  24. throws Throwable {
  25. System.out.println("宋喆代替王宝强维护微博");
  26. Object returnValue=method.invoke(realSubject,args);
  27. System.out.println("宋喆代替王宝强与粉丝互动");
  28. return returnValue;
  29. }
  30. }
  31. );
  32. proxy.request();
  33. }
  34. }
  • Cglib代理
  1. public class RealSubject {
  2. public void request() {
  3. System.out.println("王宝强拍电影");
  4. }
  5. }
  6.  
  7. import net.sf.cglib.proxy.Enhancer;
  8. import net.sf.cglib.proxy.MethodInterceptor;
  9. import net.sf.cglib.proxy.MethodProxy;
  10.  
  11. import java.lang.reflect.Method;
  12.  
  13. public class ProxyFactory implements MethodInterceptor {
  14. private Object realSubject;
  15. public ProxyFactory(Object realSubject){
  16. this.realSubject=realSubject;
  17. }
  18. public Object getProxyInstance(){
  19. //1.工具类
  20. Enhancer enhancer=new Enhancer();
  21. //2.设置父类
  22. enhancer.setSuperclass(realSubject.getClass());
  23. //3.设置回调函数
  24. enhancer.setCallback(this);
  25. //4.创建子类
  26. return enhancer.create();
  27. }
  28. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
  29. throws Throwable {
  30. System.out.println("宋喆代替王宝强维护微博");
  31. Object returnValue=method.invoke(realSubject,objects);
  32. System.out.println("宋喆代替王宝强与粉丝互动");
  33. return returnValue;
  34. }
  35. }
  36.  
  37. public class Main {
  38. public static void main(String[] args) {
  39. RealSubject realSubject=new RealSubject();
  40. RealSubject proxy=
  41. (RealSubject)new ProxyFactory(realSubject)
  42. .getProxyInstance();
  43. proxy.request();
  44. }
  45. }
  • 区别:静态代理与JDK动态代理的区别在于一个是写类去组合目标对象,一个去写匿名内部函数,二者相同之处是原类与代理类必须共同实现目标接口。而Cglib则不用实现目标接口。前两者代码维护性相对于Cglib不方便。
  • 应用场景:AOP切面编程通常可以处理事务管理(开启事务、操作、提交事务)、安全检测(权限验证,进入)、缓存(访问数据库、存入缓存)。AOP默认使用动态代理。
  1. 代理对象:拦截真实业务对象的访问
  2. 代理对象应该具有和目标对象相同的方法
  3. static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
  4. -ClassLoader loader:指明生成代理对象使用哪个类加载器
  5. -Class<?>[] interfaces:指明生成哪个对象的代理对象
  6. -InvocationHandler h:指明这个代理对象要做什么事情
  7.  
  8. public interface Person{
  9.  
  10. String sing(String name);
  11. String dance(String name);
  12. }
  13.  
  14. public class LiuDeHua implements Person{
  15. public String sing(String name){
  16. ...
  17. }
  18. public String dance(String name){
  19. ...
  20. }
  21. }
  22.  
  23. public class LiuDeHuaProxy{
  24.  
  25. private Person ldh=new LiuDeHua();
  26.  
  27. public Person getProxy(){
  28. return (Person)Proxy.newProxyInstance(
  29. LiuDeHuaProxy.class.getClassLoader(),
  30. ldh.getClass().getInterfaces(),
  31. new InvocationHandler(){
  32. @Override
  33. public Object invoke(Object proxy,Method method,Object[]args)throws Throwable{
  34. if(method.getName().equals("sing")){
  35. //调用了sing方法
  36. ...
  37. return method.invoke(ldh,args);
  38. }
  39. if(method.getName().equals("dance")){
  40. //调用了dance方法
  41. ...
  42. return method.invoke(ldh,args);
  43. }
  44. }
  45. }
  46. )
  47. }
  48. }

基于JAVA的设计模式之代理模式的更多相关文章

  1. Java基础-设计模式之-代理模式Proxy

    代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理 ...

  2. Java常见设计模式之代理模式

    指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其它相关业务的处理.比如生活中的通过代理访问网络,客户通过网络代理连接网络(具体业务),由代理服务器完成用户权限和访问限制等与 ...

  3. 基于JAVA的设计模式之组合模式

    概念 将所有对象组合成一种树形结构,有分支节点.叶子节点,分支节点可以有自己的子节点,子节点可以是分支节点.叶子节点,可以进行增删的操作,而叶子节点不可以.比如文件夹就是一个分支节点,而文件就是一个叶 ...

  4. java设计模式6——代理模式

    java设计模式6--代理模式 1.代理模式介绍: 1.1.为什么要学习代理模式?因为这就是Spring Aop的底层!(SpringAop 和 SpringMvc) 1.2.代理模式的分类: 静态代 ...

  5. Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景

    我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...

  6. 夜话JAVA设计模式之代理模式(Proxy)

    代理模式定义:为另一个对象提供一个替身或者占位符以控制对这个对象的访问.---<Head First 设计模式> 代理模式换句话说就是给某一个对象创建一个代理对象,由这个代理对象控制对原对 ...

  7. Java设计模式:代理模式(转)

    代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.这里使用到编程中的一 ...

  8. Java的三种代理模式(Spring动态代理对象)

    Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...

  9. 基于java的设计模式入门(1)——为什么要学习设计模式

    大年初一,楼主在这里给大家拜年,祝大家码上升职加薪,码上有对象结婚,码上有车有房,幸福安康. 过完年,回学校注册报道之后,大概就要回深圳到公司开始实习了.提高自己,无非就有两种方式,一是看书学习,二是 ...

随机推荐

  1. Linux 包管理基础:apt、yum、dnf 和 dpkg

    https://linux.cn/article-8782-1.html 1. apt-get 安装( 在线) 会帮我把所有的依赖包都一起安装 apt-get install xxx 安装xxx .如 ...

  2. LWIP的底层结构(物理层)

    LWIP的底层结构(物理层) 转自:http://bluefish.blog.51cto.com/214870/158418 我们前面讲到说是ip层的发送和接收都是直接调用了底层,也就是设备驱动层的函 ...

  3. MySQL Horizontal Scaling

    http://www.tuicool.com/articles/miuq63E http://www.guokr.com/blog/475765/ http://songwie.com/article ...

  4. 文件解析库doctotext安装和使用

    安装doctotext 1 安装GCC到4.6以上 tar jxf gcc-4.7.0.tar.bz2 cd gcc-4.7.0 编译 ./contrib/download_prerequisites ...

  5. Thinkphp3.2 下载文件的方法

    今天做一个功能,刚好遇到了一个要下载文件功能的需求,所以把这个基于thinkphp3.2的文件下载功能,描述一下大概的实现方法. 网上有人说用a链接的方法实现,但是这种方法并不安全.所以我们还是用官方 ...

  6. Photoshop CC 智能切图功能介绍

    http://gdc.qq.com/ http://gdc.qq.com/?p=4445

  7. swfupload原理总结

    1.引入js(js内动态添加上传的文件并提交表单) 2.后台处理(将图片保存) 3.调用另一个js修改前台图片的地址(改为新的图片地址)

  8. OVN学习(三)

    部署OVN实验环境 同OVN学习(一) 网关 在L3网络基础上部署网关 添加L3网关 ### Central节点 # ovn-sbctl show Chassis "8bd09faf-5ba ...

  9. 浅淡Java多线程

    工作中一直忙着实现业务逻辑,多线程接触得不多.对多线程的认知,一直停留在Thread和Runnable上.最近心血来潮,找了几本多线程的书,不看不知道,一看吓一跳.原来我对多线程的理解是多么的肤浅.记 ...

  10. 【TIDB】3、数据库的发展历史、现在、未来

    1.从单机数据库说起(Mysql.Oracle.PostgreSQL) 关系型数据库起源自1970年代,其最基本的功能有两个: 把数据存下来: 满足用户对数据的计算需求. 第一点是最基本的要求,如果一 ...