博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
代理模式
阅读量:5119 次
发布时间:2019-06-13

本文共 3281 字,大约阅读时间需要 10 分钟。

引用:https://www.cnblogs.com/daniels/p/8242592.html

定义:

代理是一种设计模式,是指通过代理对象来访问目标对象,通俗的来讲就像我们生活中的中介、经纪人。

作用:

中介隔离作用:客户类不想或无法直接访问目标类,可使用代理类作为客户类与目标类之间的中介

开闭原则:代理类除了作为客户类与目标类之间的中介,还可以在代理类中增加额外功能来扩展目标类的功能,

 

一、静态代理:

静态代理指的是,由程序员创建或特定工具自动生成源代码,再对其进行编译。在程序运行前,代理类的.class文件就已经存在了。

代理三要素:接口、接口实现类,接口代理类

接口:public interface BuyHouse {    public void buyHouse();}实现类:public class BuyHouseImpl implements BuyHouse {    public void buyHouse() {        System.out.println("买房");    }}静态代理类:public class StaticProxy implements BuyHouse {    private BuyHouse buyHouse;    public StaticProxy(final BuyHouse buyHouse) {        this.buyHouse = buyHouse;    }    public void buyHouse() {        System.out.println("买房前准备");        buyHouse.buyHouse();        System.out.println("买房后装修");    }}测试类:public class StaticProxyTest {    @Test    public void buyHouse(){        BuyHouse buyHouse = new BuyHouseImpl();        StaticProxy buyHouseProxy = new StaticProxy(buyHouse);        buyHouseProxy.buyHouse();    }} 结果: 买房前准备 买房 买房后装修

静态代理总结:

优点:在符合开闭原则的情况下对目标对象进行功能扩展。

        缺点:需为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。

二、JDK动态代理

在动态代理中我们不需要再手动的创建代理类,我们只需要编写一个动态处理器就可以了。真正的代理对象由JDK在运行时动态的来创建。

动态代理类:public class DynamicProxyHandler implements InvocationHandler {    private Object object;    public DynamicProxyHandler(final Object object) {        this.object = object;    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("买房前准备");        Object result = method.invoke(object, args);        System.out.println("买房后装修");        return result;    }}测试类:public class DynamicProxyHandlerTest {    @Test    public void buyHouse() {        BuyHouse buyHouse = new BuyHouseImpl();        BuyHouse buyHouseProxy = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new Class[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));        buyHouseProxy.buyHouse();    }}结果:买房前准备买房买房后装修

注意Proxy.newProxyInstance()方法接受三个参数:

  • ClassLoader loader:指定当前目标对象使用的类加载器
  • Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
  • InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法

jdk动态代理总结:

代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理

三、CGLib动态代理

cglib通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用

动态代理类:public class CglibProxy implements MethodInterceptor {    private Object target;    public Object getInstance(final Object target) {        this.target = target;        Enhancer enhancer = new Enhancer();         //设置为父类        enhancer.setSuperclass(this.target.getClass());         //设置回调函数        enhancer.setCallback(this);         //创建之类        return enhancer.create();    }    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {        System.out.println("买房前准备"); //执行目标对象的方法        Object result = method.invoke(target, args);        System.out.println("买房后装修");        return result;    }}测试类:public class CglibProxyTest {    @Test    public void buyHouse() {        BuyHouse buyHouse = new BuyHouseImpl();        CglibProxy cglibProxy = new CglibProxy();        BuyHouse buyHouseProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse);        buyHouseProxy.buyHouse();    }}结果:买房前准备买房买房后装修

CGLib动态代理总结:

CGLib由于是采用动态创建子类的方法,对于final修饰的方法无法进行代理。

 

转载于:https://www.cnblogs.com/tilamisu007/p/9392284.html

你可能感兴趣的文章
雅礼集训2019 day5
查看>>
去除一段文字最后一个符号
查看>>
支持向量机
查看>>
Hadoop之HDFS原理及文件上传下载源码分析(下)
查看>>
glusterfs分布式文件系统
查看>>
[Swift]学习笔记-可选类型/可选链
查看>>
正态分布的前世今生
查看>>
使用yum高速部署Oracle安装环境(11g)
查看>>
HTML在Select具体的使用说明
查看>>
周期串 字符串的最小正周期
查看>>
用JSP实现的商城购物车模块
查看>>
Tomcat全攻略
查看>>
ionic2的返回按钮的编辑问题
查看>>
JavaScript数据存储和深浅拷贝实际运用
查看>>
socket随笔
查看>>
块级元素和行内元素
查看>>
What Zabbix can do for you?
查看>>
编译BusyBox12.0
查看>>
Demo排查C++函数重载几个疑点
查看>>
SQLServer中日期函数有关年份、月份、星期
查看>>