设计模式之代理模式

导读:本篇文章讲解 设计模式之代理模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

静态代理,动态代理是什么? JDK动态代理,cglib动态代理。

目录

什么是代理模式?

静态代理

代理模式的优缺点

动态代理

JDK动态代理实现

cglib动态代理

 静态代理 动态代理比较

Cglib和jdk动态代理的区别?

什么时候用cglib什么时候用jdk动态代理?

JDK动态代理和cglib字节码生成的区别?

Cglib比JDK快?


什么是代理模式?

角色:一个接口(一类业务

 public interface Rent {
     public void rent();
     public void add();
     public void delete();
 }

接口的实现类(具体的实现方法

 public class Host implements Rent{
     @Override
     public void rent() {
         System.out.println("租房子了");
     }
 ​
     public void add(){
         System.out.println("增加");
     }
     public void delete(){
         System.out.println("删除");
     }
 }

用户想要使用这个具体的方法 就需要调用 具体的实现类 impl

但是又不想直接访问 就用另外一个代理类来代替他 做一个封装

静态代理

生成一个 HostP 对象,这个对象内部可以实现原先 host 的所有功能,并且可以扩展一些功能,但实际上里面的功能还是由 host 提供的。

 public class HostP implements Rent{
 ​
     private Host host;
     public void setHost(Host host) {
         this.host = host;
     }
     @Override
     public void rent() {
         host.rent();
     }
     @Override
     public void add() {
         host.add();
     }
     public void delete(){
         System.out.println("delete 租户");
     }
 }

代理模式的优缺点

使用代理模式具有以下几个优点:

1、代理模式能将代理对象与真实被调用的目标对象分离。

2、一定程度上降低了系统的耦合度,扩展性好。

3、可以起到保护目标对象的作用。

4、可以对目标对象的功能增强。

当然,代理模式也是有缺点的:

1、代理模式会造成系统设计中类的数量增加。

2、在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。

3、增加了系统的复杂度。
————————————————
版权声明:本文为CSDN博主「Leon_Jinhai_Sun」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Leon_Jinhai_Sun/article/details/109553543

动态代理

JDK动态代理实现

技术:java反射

前提:代理的类实现了接口。

通过newProxyInstance()函数获得proxy对象,这个对象就代理了实现了这个接口所有的类,然后使用这个代理对象即可。 代理对象会自动调用相应的方法。比如

  • IRpcHelloService RpcHello = RpcProxy.create(IRpcHelloService.class);

  • System.out.println(RpcHello.hello("Tom老师"));

RpcHello IRpcHelloService.class这个接口的代理类,IRpcHelloServiceImpl实现了这个接口,那么RpcHello.hello("Tom老师")就相当于调用了IRpcHelloServiceImpl中的hello方法。

newProxyInstance,方法有三个参数:

loader: 用哪个类加载器去加载代理对象

interfaces:动态代理类需要实现的接口

h:动态代理方法在执行时,会调用h里面的invoke方法去执行

public class ProxyHost implements InvocationHandler {

    private Object target;
	// 注入一个实现类  
    public void setTarget(Object target) {
        this.target = target;
    }
	// 根据实现类  拿到其实现的方法
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }
    // 在使用时直接调用方法即可  
    // 调用时就会通过 invoke来实现
    @Override
    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
        System.out.println("调用方法前的日志");// 在调用原对象的方法时  可以增强
        Object result = method.invoke(target,args);
        System.out.println("调用方法后的日志");
        return result;
    }

}

cglib动态代理

代理模式实现方式及优缺点对比 – 上台阶 – 博客园

 静态代理 动态代理比较

设计模式之代理模式

Cglib和jdk动态代理的区别?

Cglib和jdk动态代理的区别及运行性能比较 – 沐春风-燕南飞 – 博客园

经测试,jdk创建对象的速度远大于cglib,这是由于cglib创建对象时需要操作字节码。

cglib执行速度略大于jdk,所以比较适合单例模式。

1、Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理

2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理

什么时候用cglib什么时候用jdk动态代理?

1、目标对象生成了接口 默认用JDK动态代理

2、如果目标对象使用了接口,可以强制使用cglib

3、如果目标对象没有实现接口,必须采用cglib库,Spring会自动在JDK动态代理和cglib之间转换

JDK动态代理和cglib字节码生成的区别?

1、JDK动态代理只能对实现了接口的类生成代理,而不能针对类

2、Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法的增强,但是因为采用的是继承,所以该类或方法最好不要生成final,对于final类或方法,是无法继承的

Cglib比JDK快?

1、cglib底层是ASM字节码生成框架,但是字节码技术生成代理类,在JDL1.6之前比使用java反射的效率要高

2、在jdk6之后逐步对JDK动态代理进行了优化,在调用次数比较少时效率高于cglib代理效率

3、只有在大量调用的时候cglib的效率高,但是在1.8的时候JDK的效率已高于cglib

4、Cglib不能对声明final的方法进行代理,因为cglib是动态生成代理对象,final关键字修饰的类不可变只能被引用不能被修改

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92849.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!