前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java设计模式之静态代理和动态代理(简单例子)

Java设计模式之静态代理和动态代理(简单例子)

作者头像
程裕强
发布2022-05-06 19:44:43
1780
发布2022-05-06 19:44:43
举报

1、代理模式

一个生活中的例子:明星都有一个自己的经纪人,这个经纪人就是他们的代理人。 当我们需要找明星表演时,不能直接找到该明星,只能是找明星的代理人。比如张学友在没有出名之前,我们可以直接找他唱歌,跳舞,拍戏;但是张学友出名之后,他干的第一件事就是找一个经纪人,这个经纪人就是张学友的代理人(代理)。 当我们需要找刘德华表演时,不能直接找到张学友了,只能是找其代理人,具体事务和代理人谈,相当于和张学友本人洽谈。张学友这个代理人存在的价值就是拦截我们对张学友的直接访问

这个现实中的例子和我们在开发中是一样的,我们在开发中之所以要产生一个对象的代理对象,主要用于拦截对真实业务对象的访问。那么代理对象应该具有什么方法,代理对象应该具有和目标对象相同的方法。

一个典型的代理模式通常有三个角色(代理三要素)

  • 接口,接口中的方法是要真正去实现的
  • 被代理类,实现上述接口,这是真正去执行接口中方法的类
  • 代理类,帮助被代理类去实现方法

2、静态代理

若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类。

(1)共同接口

代码语言:javascript
复制
public interface Action {
    void sing(String name);//唱歌
}

(2)真实对象

代码语言:javascript
复制
public class Star implements Action{//明星
    @Override
    public void sing(String name){
        System.out.println("下面为大家演唱:"+name);
    }
}

(3)代理人

代码语言:javascript
复制
public class Proxy implements Action{
    private Action person;

    public Proxy(Action person) {
        this.person = person;
    }

    @Override
    public void sing(String name) {
        System.out.println("代理人通知明星:");
        person.sing(name);
    }
}

(4)测试

代码语言:javascript
复制
public class Main {
    public static void main(String[] args) {
        Proxy proxy = new Proxy(new Star());
        proxy.sing("饿狼传说");
    }
}

(5)运行结果

代码语言:javascript
复制
代理人通知明星:
下面为大家演唱:饿狼传说

3、动态代理

静态代理的局限在于运行前必须编写好代理类(当多个对象需要代理时,需要事先定义好对应代理类)。 动态代理的目的就是为了解决静态代理的不足,动态代理的代理类是在程序运行期间动态生成的。

使用动态代理的五大步骤

  1 通过实现InvocationHandler接口来自定义自己的InvocationHandler。

  2 通过Proxy类的getProxyClass方法获取代理类。

  3 通过反射机制获取代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)。

  4 将目标对象作为参数传入,通过构造方法获取自定义的InvocationHandler实例对象。

  5 将自定义的InvocationHandler实例对象作为参数传入,通过构造方法获取代理对象。

  6 代理对象调用目标方法。

代码语言:javascript
复制
package dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicProxyHandler implements InvocationHandler {
    private Object person;

    public DynamicProxyHandler(Object person) {
        this.person = person;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //代理扩展逻辑
        System.out.println("代理人通知被代理人:");
        return method.invoke(person, args);
    }
}
代码语言:javascript
复制
package dynamic;

import java.lang.reflect.Proxy;
import proxy.Action;
import proxy.Star;

public class DynamicProxyDemo {
    public static void main(String[] args) {
        Star star = new Star();
        Action proxy = (Action)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Action.class}, new DynamicProxyHandler(star));
        proxy.sing("饿狼传说");
    }
}

Proxy.newProxyInstance 传入的是一个ClassLoader, 一个代理接口,和我们定义的handler,返回的是一个Proxy的实例。 运行结果

代码语言:javascript
复制
代理人通知被代理人:
下面为大家演唱:饿狼传说
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

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