前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java动态代理与静态代理的区别

java动态代理与静态代理的区别

作者头像
用户9854323
发布2022-10-04 08:17:09
1760
发布2022-10-04 08:17:09
举报
文章被收录于专栏:小陈飞砖小陈飞砖

一、静态代理

静态代理的代理类和被代理类有一个相同的接口:

接口:

代码语言:javascript
复制
public interface HelloInterface {
    void sayHello();
    void sayNo(String no);
    String callYes(int number,String yes);
}

被代理类:

代码语言:javascript
复制
public class Hello implements HelloInterface{
    
    @Override
    public void sayHello() {
        System.out.println("Hello zhanghao!");
    }

    @Override
    public void sayNo(String no) {
    }

    @Override
    public String callYes(int number, String yes) {
        Log.i("ProxyHandler", "Hello callYes " + number + " " + yes);
        return "yes";
    }
}

代理类:

代码语言:javascript
复制
public class HelloProxy implements HelloInterface{

    private HelloInterface helloInterface;

    public HelloProxy(HelloInterface helloInterface){
        this.helloInterface = helloInterface;
    }

    @Override
    public void sayHello() {
        System.out.println("Before invoke sayHello" );
        helloInterface.sayHello();
        System.out.println("After invoke sayHello");
    }

    @Override
    public void sayNo(String no) {
        System.out.println("Before invoke sayHello" );
        helloInterface.sayNo(no);
        System.out.println("After invoke sayHello");
    }

    @Override
    public String callYes(int number, String yes) {
        System.out.println("Before invoke sayHello" );
        return helloInterface.callYes(number, yes);
    }
}

使用静态代理:

代码语言:javascript
复制
public static void call() {
        HelloProxy helloProxy = new HelloProxy(new Hello());

        helloProxy.sayHello();
        helloProxy.sayNo("no");
        helloProxy.callYes(1, "yes");
    }

静态代理的优点: 如果是相同接口下的被代理类,可以使用同一个代理类。

静态代理的缺点: 但如果是不同接口的被代理类,则需要再写一个冗长代理类。 另外代理类中需要实现所有被代理类的方法。

二、动态代理

动态代理则弥补了上述静态代理的缺点: 1、如果换不同的接口的被代理类,不用再写一个冗长的代理类,Proxy.newProxyInstance()出来一个代理类就可以。

2、代理类不用实现所有的被代理的方法,一个InvocationHandler 的 invoke() 方法中使用method.invoke(object, args)可以实现。

例如:

代码语言:javascript
复制
public class ProxyHandler implements InvocationHandler {

    private Object object;

    public ProxyHandler(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String argss = "null";
        if(args != null){
            argss = args[0].toString();
        }
        Log.i("ProxyHandler", "Before invoke  " + object.getClass().getSimpleName()
                + " " + method.getName() + "  " + argss);
        method.invoke(object, args);
        return null;
    }
}

动态代理对上述Hello.java的调用:

代码语言:javascript
复制
public static void remoteHello() {

        HelloInterface hello = new Hello();

        HelloInterface helloProxy = (HelloInterface) Proxy.newProxyInstance(
                hello.getClass().getClassLoader(), hello.getClass().getInterfaces(),
                new ProxyHandler(hello));

        helloProxy.sayHello();
        helloProxy.sayNo("no");
        helloProxy.callYes(1, "s");
    }

例如,再代理一个PersonInterface,不用再写代理类:

代码语言:javascript
复制
public interface PersonInterface {
    void getName();
    void setColor(String color);
    String doString(int number, String yes);
}

被代理类如下Person.java :

代码语言:javascript
复制
public class Person implements PersonInterface {

    @Override
    public void getName() {
    }

    @Override
    public void setColor(String color) {
    }

    @Override
    public String doString(int number, String yes) {
        Log.i("ProxyHandler", "Person doString " + number + " " + yes);
        return null;
    }
}

调用时如下所示:

代码语言:javascript
复制
public static void remotePerson() {

        PersonInterface person = new Person();
        PersonInterface personProxy = (PersonInterface) Proxy.newProxyInstance(
                person.getClass().getClassLoader(), person.getClass().getInterfaces(),
                new ProxyHandler(person));

        personProxy.getName();
        personProxy.setColor("s");
        personProxy.doString(1, "d");
    }

动态代理的优势: 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。 想想你有100个静态代理类,现在有一个需求,每个代理类都需要新增一个处理逻辑,你需要打开100个代理类在每个代理方法里面新增处理逻辑吗? 有或者代理类有5个方法,每个方法都需要新增一个处理逻辑, 你需要在每个方法都手动新增处理逻辑吗? 想想就挺无趣的。动态代理类帮你一键搞定。

动态代理的缺点: 1、JDK动态代理需要业务实现类所实现的接口。如果业务实现类是没有实现接口而是直接定义业务方法的话,就无法使用JDK动态代理了。(JDK动态代理重要特点是代理接口) 并且,如果业务实现类中新增了接口中没有的方法,这些方法是无法被代理的(因为无法被调用)。动态代理只能对接口产生代理,不能对类产生代理。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、静态代理
  • 二、动态代理
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档