文档章节

Java面试基础篇——第十五篇:代理模式

liululee
 liululee
发布于 2018/08/02 21:11
字数 761
阅读 114
收藏 11

##什么是代理? 通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理。 ##代理应用场景 安全代理 可以屏蔽真实角色 远程代理 远程调用代理类RMI 延迟加载 先加载轻量级代理类,真正需要在加载真实 ##代理的分类

  • 静态代理(静态定义代理类)
  • 动态代理(动态生成代理类) 如 Jdk自带动态代理, Cglib, javaassist(字节码操作库)

接下来举个Sam卖房子的例子来看看三种代理模式: 静态代理,jdk自带动态代理,cglib动态代理。项目构建基于springboot。 ##静态代理 卖房接口类

public interface House {
    //卖房
    void sale();
}

Sam类实现卖房接口

public class Sam implements House {
    @Override
    public void sale() {
        System.out.println("I'm Sam, I want sale my house !");
    }
}

静态代理类,帮Sam卖房。

public class Proxy implements House {
    private Sam sam;

    public Proxy(Sam sam){
        this.sam = sam;
    }

    @Override
    public void sale() {
        System.out.println("proxy listening sale start");
        sam.sale();
        System.out.println("proxy listening sale end");
    }

    public static void main(String[] args) {
        Sam sam = new Sam();
        Proxy proxy = new Proxy(sam);
        proxy.sale();
    }

}

jdk动态代理

通过反射机制来实现调用卖房方法。需要注意的是要实现InvocationHandler。

/**
 * Jdk 动态代理
 */
public class JDKProxy implements InvocationHandler {

    public Object target;

    public JDKProxy (Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我是房产中介,使用JDK动态代理监听");
        Object invoke = method.invoke(target, args);
        System.out.println("监听完成!");
        return invoke;
    }

    public static void main(String[] args) {
        Sam sam = new Sam();
        JDKProxy jdkProxy = new JDKProxy(sam);
        House house = (House) Proxy.newProxyInstance(sam.getClass().getClassLoader(), sam.getClass().getInterfaces(), jdkProxy);
        house.sale();

    }
}

cglib动态代理

需要注意的是要实现MethodInterceptor接口。

public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib 代理开始监听你了  ");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("cglib 代理监听完成了! ");
        return object;
    }

    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        //使用sam框架
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Sam.class);
        enhancer.setCallback(cglibProxy);
		//asm框架生成
        House house = (House) enhancer.create();
        house.sale();
    }
}

cglib 与jdk 动态代理的区别

jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。 还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。

注:asm其实就是java字节码控制.

© 著作权归作者所有

liululee
粉丝 127
博文 66
码字总数 90743
作品 0
杭州
程序员
私信 提问
20个设计模式和软件设计面试问题

不管是参加Java面试还是C#面试,设计模式和软件设计都是任何编程面试中的必问问题。实际上,编程能力和设计技巧是对彼此很好的补充。一个好的程序员通常都是一个好的软件设计人员。他们知道怎...

LCZ777
2014/08/13
98
0
为什么java中用枚举实现单例模式会更好

枚举单例是java中使用枚举提供一个实例对象来实现单例模式的一种新方法,虽然单例模式在java中早已存在,但枚举单例实际上从java5引入枚举作为它的关键特性之后相对来说还是一个新的概念,这...

zhoujy
2013/06/01
8.8K
1
python 与设计模式 ——工厂与单例

python 与设计模式 源码地址:[http://git.oschina.net/duoduo3_69/python_design_pattern][1] git checkout v001(这个版本与此篇博客相符) zarkpy里面运用了很多设计模式,以前一直很费解p...

duoduo3_69
2013/11/27
885
0
Android--面试中遇到的问题总结(三)

《Android 开发工程师面试指南 LearningNotes 》,作者是陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备...

sealin
2017/02/22
0
0
【Java学习路线】新手该如何一步步的学习 Java

新手该如何一步步的学习 Java? 如果真的想学Java,最好要循序渐进,有章有法的学习它! 今天小慕就不说一些学习方法和技巧了,直接来谈每个阶段要学习的内容。 首先,给大家分享一张以 企业...

Eddie_yang
2018/11/15
2.3K
0

没有更多内容

加载失败,请刷新页面

加载更多

怎样在磁盘上查找MySQL表的大小?这里有答案

我想知道 MySQL 表在磁盘上占用多少空间,但看起来很琐碎。不应该在 INFORMATION_SCHEMA.TABLES 中提供这些信息吗?没那么简单! 我想知道 MySQL 表在磁盘上占用多少空间,但看起来很琐碎。不应...

Linux就该这么学
45分钟前
5
0
Redis

一、Redis支持的几种数据类型:字符串、List、SET、HASH、ZSET 二、Redis的缓存技术主要是为了降低关系数据库的负载并减少网站成本 三、在Redis里面,被MULTI命令和EXEC命令包围的所有命令会...

BobwithB
47分钟前
4
0
MongoDB基础之入门

MongoDB基础之入门 一、MONGODB简介 MongoDB由C/C++开发,是一种强大、灵活、可扩展的数据存储方式。它扩展了关系型数据库的众多有用功能,例如:辅助索引、范围查询和排序。MongoDB还内置了...

星汉
49分钟前
7
0
c++ 神奇的赋值用法

c++ 神奇的赋值用法(第8章)

天王盖地虎626
今天
5
0
Jquery操作UI之设置字体大小

先获取字体大小,进行处理。再将修改的值保存。 slice() 方法可从已有的数组中返回选定的元素。 arrayObject.slice(start,end)。 start 必需。规定从何处开始选取。如果是负数,那么它规定从...

前端老手
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部