模糊的概念(2)

这种概念的模糊,还是因为当时在看书或者学习某一个知识点的时候,没有能够把这个知识变为自己的东西,停留在比较浅层次的理解的基础上面,没有能够真正的运用上面,就像那些笑话中所说的一样,“这些道理臣妾都明白,可就是过不好日子”。道理光是明白肯定是过不好日子的,明白了,理解了,最重要的是想办法去应用,把学到的知识最终归到自己的知识体系里面,这样才算是真正的明白,才有过好日子的可能。

继续说设计模式:代理的设计模式,以前的理解,比较的高效,认为代理就是请求来临的时候,代理对象首先执行,然后在去执行被代理对象的方法。如果按照这种大而化之的理解,那么组合类里面的任何一个调用都是代理模式了。

还是首先是简单的UML:

真正的对象和代理对象都会实现这个接口,然后在调用的时候,调用的是代理的对象,然后代理的对象再去调用真正的对象。

// 抽象角色:
abstract public class Subject {
    abstract public void  request();
}

// 真实角色:实现了Subject的request()方法
public class  RealSubject  extends  Subject  {
  public  RealSubject()  { }

  public void  request()  {
     System.out.println( " From real subject. " );
    }
}

// 代理角色:
public class  ProxySubject  extends  Subject  {
  // 以真实角色作为代理角色的属性
  private  Subject realSubject;

  public  ProxySubject(Subject realSubject)  {this.realSubject = realSubject }

  // 该方法封装了真实对象的request方法
  public void  request()  {
     preRequest();
     realSubject.request();  // 此处执行真实对象的request方法
     postRequest();
  }
  ...
}

// 客户端调用:
RealSubject real = new RealSubject();
Subject sub = new  ProxySubject(real);
Sub.request();

还有一种方式是继承的方式:

核心的代码是:

//dosomething before
    super.doOperation()
   //dosomething after
  1. 采用父类的调用,不用接口的这种方式。

一般的情况下,真是的对象应该增加访问的限制,例如:不能够在外部的访问。

说到了代理模式,JDK实现了一个动态代理的模式,为什么会有这个动态代理,因为上面虽然实现了代理,但是每一个类一个代理的话,代码呈现臃肿,并且也不符合同一个功能对应一块或者一个类,或者说抽象封装的设计理念,所以就有了JDK的动态代理,其UML是:

具体的代码:

package regularExpression.current;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface ISubject {
    public void showName(String name);
}

class RealSubject implements ISubject {

    @Override
    public void showName(String name) {
        System.out.println(name+"闪亮登场");
    }

}

class LogHandler implements InvocationHandler {

    Object target=null;

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result=null;
        //调用目标对象方法前的逻辑
        System.out.println("下面有一个大人物要出现");
        //调用目标对象的方法,这句代码将代理与目标类联系了起来
        method.invoke(target, args);
        //调用目标对象方法后的逻辑
        System.out.println("大家鼓掌欢迎");
        return result;

    }

}
public class Client {
    /**
     * @param args
     */
    public static void main(String[] args) {

        LogHandler logHandler=new LogHandler();
        logHandler.setTarget(new RealSubject());
        //创建代理对象
        ISubject proxySubject=(ISubject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(), RealSubject.class.getInterfaces(), logHandler);
        System.out.println("-------JDK Proxy-------------");
        proxySubject.showName("委座");

    }

}

看到这个方法:java.lang.reflect.Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler) 应该能够推出来:

JDK的动态代理,必须的要实现了接口的类才能够有动态代理,不然的话,在类Proxy的方法:

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException

无法建立代理的实例,就无法代理了,但是cglib可以,具体的UML为:

可以看到的是RealSubject 不需要实现一个接口,

class LogIntercept implements MethodInterceptor {
    Object target=null;

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    @Override
    public Object intercept(Object arg0, Method arg1, Object[] arg2,
            MethodProxy arg3) throws Throwable {

        Object result=null;
        //调用目标对象方法前的逻辑
        System.out.println("下面有一个大人物要出现");
        //调用目标对象的方法,这句代码将代理与目标类联系了起来
        arg3.invoke(target, arg2);
        //调用目标对象方法后的逻辑
        System.out.println("大家鼓掌欢迎");
        return result;
    }

}

调用的方式:

LogIntercept logIntercept=new LogIntercept();
        logIntercept.setTarget(new RealSubject());
        RealSubject proxySubject1=(RealSubject )Enhancer.create(RealSubject.class, logIntercept);
        System.out.println("-------CBLIB-------------");
        proxySubject1.showName("委座");

这也就能够理解spring提供两种代理方式的原因:

目标对象有没有实现接口Spring都会选择使用CGLIB代理。所以在默认情况下,如果一个目标对象如果实现了接口,Spring则会选择JDK动态代理策略动态的创建一个接口实现类(动态代理类)来代理目标对象,可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间在强制转换的时候会抛出j ava.lang.ClassCastException。而所以在默认情况下,如果目标对象没有实现任何接口,Spring会选择CGLIB代理, 其生成的动态代理对象是目标类的子类。

代理模式这样算是到一个阶段,这样才能够穿起来,理清一个点。

时间: 2024-08-13 13:22:17

模糊的概念(2)的相关文章

模糊的概念(三)

知易行难啊,自己到底还有多少没有理解明白的,为什么一刨根问底,全部都哑火了?继续的设计模式,最起码常见的设计模式,要说清楚吧. 说完了代理模式,我们在理清和代理模式比较像的装饰模式,这个模式的UML为: 具体的应用是: 装饰模式中比较典型的调用方式:InputStream input = new DataInputStream(new FileInputStream(new File(""))); 说到了流了,字节流和字符流在转化的时候,使用的一种模式叫做:适配器模式,典型的两个类为:

第五十一课 NoSQL基础概念及MongoDB应用、数据库分配概念

NoSQL基础概念及MongoDB MongoDB基础应用 MongoDB索引及复制集 数据库分片的概念及Mongodb  sharding的实现 一.NoSQL基础概念 NoSQL(Not Only SQL),是一种技术流派,非关系型数据库:适合用在大数据领域,各种nosql有各自的查询语句,这也是nosql的缺点之一. 大数据(BigDate)也称海量数据是一个模糊的概念,像Google.百度收集大量数据,分析现在.预测未来:这些数据通过某些特定的特征和算法得出某些预测的结果,这些数据为大数

嵌入式科普:基本概念,设计流程,开发特点,如何学习

本文涉及的内容较多,个人知识水平有限,如有不当之处欢迎指正. 特别鸣谢:嵌入式大神 @tofulee ,@woshizmxin 对本文给出了一些很好的意见. 何为嵌入式 嵌入式是一个比较模糊的概念,也没有很准确的解释,其实也没必要一定找出个准确的解释来,并不影响学习. 参考了网上的资料,根据我的认识,可以认为嵌入式系统是一种完全嵌入到设备内部.解决特定问题的专用计算机.我们常用的电脑被认为是通用计算机,能安装各种软件,从而解决各种不同问题:而嵌入式系统是专用计算机,只负责解决特定问题,例如控制洗

浅析数据结构-图的基本概念

线性表和树两类数据结构,线性表中的元素是“一对一”的关系,树中的元素是“一对多”的关系,本章所述的图结构中的元素则是“多对多”的关系.图(Graph)是一种复杂的非线性结构,在图结构中,每个元素都可以有零个或多个前驱,也可以有零个或多个后继,也就是说,元素之间的关系是任意的. 一.图的定义与术语 定义:图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合. 1.图的分类 图是按照无方向和有方向分为无向

开发接口,你需要先搞懂这些概念!

SOA Service Oriented Ambiguity 即面向服务架构, 简称SOA. SOA的提出是在企业计算领域,就是要将紧耦合的系统,划分为面向业务的,粗粒度,松耦合,无状态的服务.服务发布出来供其他服务调用,一组互相依赖的服务就构成了SOA架构下的系统. 首先,你要知道SOA并不是某一种具体的技术实现,它是一个系统架构的设计思想.这个架构设计思想的提出背景是随着我们的软件系统解决的问题越来越复杂,那么会带来难以维护.难以扩展,容易出错等问题.那么SOA思想的提出就是为了解决这个问题

“挖掘机”升级路 一篇(03)--HBase集群安装中的收获

粗略算算,从上周五到这周二,折腾Hadoop已经三天了.这三天我是过得诚惶诚恐,作为一个学徒,老大虽然没有说啥,但是我恨不得立马完成这些基本的部署工作,感觉拖了好久好久.简单的总结一下,第一天折腾Hadoop单机和伪分布式的安装,第二天在折腾Hive的安装,以失败告终,第三天折腾HBase的集群安装,在主节点上安装成功. 也就来具体的谈谈今天的收获,今天的参考资料主要是这么两篇1.分布式实时日志系统(四) 环境搭建之centos 6.4下hbase 1.0.1 分布式集群搭建(我FQ看的,不知道

如何提升网站在移动端的打开速度(转)

原文来自:http://www.studyofnet.com/news/173.html 本文导读:"移动网络"是个非常模糊的概念, 2g 3g wifi都是移动网络,但是网络特性以及对应的优化方法还是有些区别的. 对于移动端而言,可能最需要关注的是移动网络环境下的访问速度. 重点是减少网络传输量和交互次数, 善用本地缓存. 大部分人对移动端的浏览体验感到失望,同时当体验提升时,他们会在智能手机上花费更多的时间.因为64%的智能手机用户希望网站可以在4秒内加载完毕,但一半的网站花费了二

(转)内存堆和栈的区别

原文: http://student.csdn.net/link.php?url=http://www.top-e.org%2Fjiaoshi%2Fhtml%2F427.html 在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认识,因为我曾经就是这么想的和汇编语言中的堆栈一词混为一谈.我身边的一些编程的朋友以及在网上看帖遇到的朋友中有好多也说不清

C#中委托和事件

目 录 1.1 理解委托 2 1.1.1 将方法作为方法的参数 2 1.1.2 将方法绑定到委托 4 1.2 事件的由来 6 1.2.1 更好的封装性 6 1.2.2 限制类型能力 9 1.3 委托的编译代码 10 1.4 .NET 框架中的委托和事件 11 1.4.1 范例说明 11 1.4.2 Observer 设计模式简介 12 1.4.3 实现范例的Observer 设计模式 13 1.4.4 .NET 框架中的委托与事件 14 1.5 委托进阶 16 1.5.1 为什么委托定义的返回值