代理模式的学习总结

代理模式

  1. 静态代理
    需要为每个代理者(类、接口)都创建一个代理类,让代理类继承或实现被代理者,重写被代理
    者中的方法,重写之后就可以增加业务逻辑,还需要调用被代理者中的方法
  2. 动态代理
    1、JDK自带实现多态代理的方法(Proxy)
    1.1要求被代理类(目标类)需要实现一个接口
    1.2、步骤
    1.2.1、创建被代理者类的对象(目标对象)
    1.2.2、获取目标类的类加载器:ClassLoader对象
    1.2.3、获取目标类所实现的所有接口
    1.2.4、需要创建InvocationHandler对象
    2、CGLib

静态代理

/*
我们将创建一个 Image 接口和实现了 Image 接口的实体类。ProxyImage 是一个代理类,减少 RealImage 对象加载的内存占用。

ProxyPatternDemo,我们的演示类使用 ProxyImage 来获取要加载的 Image 对象,并按照需求进行显示。

简单来说,代理类就是比原来的类的功能更加的强大,功能更全
 */
public class StaticProxyDemo {
    public static void main(String[] args) {
        Image image = new ProxyImage("lhm.jpg");

        //需要从内存中加载
        image.disPlay();

        System.out.println("---------------");
        //不需要从内存中加载
        image.disPlay();
    }
}

interface Image{
    void disPlay();
}

class RealImage implements Image{
    private String fileName;

    public RealImage(String fileName){
        this.fileName = fileName;
        loadFromDisk(fileName);
    }

    private void loadFromDisk(String fileName){
        System.out.println("正在从磁盘加载图片....");
    }
    @Override
    public void disPlay() {
        System.out.println("展示的图片是:" + fileName);
    }
}

class ProxyImage implements Image{
    private RealImage ri;
    private String fileName;

    public ProxyImage(String fileName){
        this.fileName = fileName;
    }
    @Override
    public void disPlay() {
        if (ri == null){
            ri = new RealImage(fileName);
        }
        ri.disPlay();
    }
}

动态代理

/*
1、动态代理
    ava.lang.reflect.Proxy:生成动态代理类和对象;
    java.lang.reflect.InvocationHandler(处理器接口):可以通过invoke方法实现对真实角色的代理访问。
    每次通过 Proxy 生成的代理类对象都要指定对应的处理器对象。
2、步骤
    1、创建被代理者类的对象(目标对象)
    2、获取目标类的类加载器:ClassLoader对象
    3、获取目标类所实现的所有接口
    4、需要创建InvocationHandler对象
 */
public class DynamicProxyDemo {
    public static void main(String[] args) {
        RealSubject rs= new RealSubject();

        //MyInvocationHandler mih = new MyInvocationHandler(rs);
        /*Subject proxySubject = (Subject) Proxy.newProxyInstance(*//*ClassLoader.getSystemClassLoader(),*//* Subject.class.getClassLoader(),
                RealSubject.class.getInterfaces(),
                mih);*/

        Subject proxySubject = (Subject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
                RealSubject.class.getInterfaces(),
                (proxy, method, args1) -> {
                    if (method.getName().equalsIgnoreCase("says")){
                        System.out.println("说话方法");
                        return method.invoke(rs, args1);
                    }else if (method.getName().equalsIgnoreCase("sellbooks")){
                        System.out.println("卖书方法");
                        return method.invoke(rs, args1);
                    }
                    return null;
                });
        proxySubject.sellBooks();
        System.out.println("==============================");
        proxySubject.Says();
        System.out.println("------------------------------");
        System.out.println(proxySubject);//对象输出值为null

        boolean present = Optional.of(proxySubject).isPresent();
        System.out.println(present);//true有值非空

        System.out.println(proxySubject instanceof Subject);//true
    }
}

interface Subject{
    void sellBooks();
    void Says();
}

class RealSubject implements Subject{
    @Override
    public void sellBooks() {
        System.out.println("卖书");
    }

    @Override
    public void Says() {
        System.out.println("和客人说话");
    }
}

class MyInvocationHandler implements InvocationHandler{
    private Subject sb;

    public MyInvocationHandler(Subject sb){
        this.sb = sb;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        /*
        proxy:代理类
        method:正在调用的方法
        args:方法的参数
         */
        System.out.println("调用代理类...");
        if (method.getName().equalsIgnoreCase("sellBooks")){
            method.invoke(sb,args);
            System.out.println("调用的卖书的方法");
        }else if (method.getName().equalsIgnoreCase("Says")){
            method.invoke(sb,args);
            System.out.println("调用的是说话的方法");
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值