文档章节

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

liululee
 liululee
发布于 2018/08/02 21:11
字数 761
阅读 111
收藏 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
粉丝 125
博文 51
码字总数 54981
作品 0
杭州
程序员
私信 提问
20个设计模式和软件设计面试问题

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

LCZ777
2014/08/13
96
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
880
0
Android--面试中遇到的问题总结(三)

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

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

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

Eddie_yang
2018/11/15
2.1K
0

没有更多内容

加载失败,请刷新页面

加载更多

SpringBoot中 集成 redisTemplate 对 Redis 的操作(二)

SpringBoot中 集成 redisTemplate 对 Redis 的操作(二) List 类型的操作 1、 向列表左侧添加数据 Long leftPush = redisTemplate.opsForList().leftPush("name", name); 2、 向列表右......

TcWong
今天
4
0
排序––快速排序(二)

根据排序––快速排序(一)的描述,现准备写一个快速排序的主体框架: 1、首先需要设置一个枢轴元素即setPivot(int i); 2、然后需要与枢轴元素进行比较即int comparePivot(int j); 3、最后...

FAT_mt
昨天
4
0
mysql概览

学习知识,首先要有一个总体的认识。以下为mysql概览 1-架构图 2-Detail csdn |简书 | 头条 | SegmentFault 思否 | 掘金 | 开源中国 |

程序员深夜写bug
昨天
10
0
golang微服务框架go-micro 入门笔记2.2 micro工具之微应用利器micro web

micro web micro 功能非常强大,本文将详细阐述micro web 命令行的功能 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go-micro环境, golang微服务框架...

非正式解决方案
昨天
7
0
前端——使用base64编码在页面嵌入图片

因为页面中插入一个图片都要写明图片的路径——相对路径或者绝对路径。而除了具体的网站图片的图片地址,如果是在自己电脑文件夹里的图片,当我们的HTML文件在别人电脑上打开的时候图片则由于...

被毒打的程序猿
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部