设计模式 2 代理模式-静态或者动态

Posted 健康平安的活着

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式 2 代理模式-静态或者动态相关的知识,希望对你有一定的参考价值。

一 代理模式

1.1 代理模式

以房东,中介,买卖房子为例子,说明什么是代理,说白就是房东卖房子因为一些利益,或者怕麻烦,没有经商头脑等各种原因,不能和客户直接进行接触买卖房子,这时候需要中介代理其进行卖房子。

1.2 代理优点:

优点一:可以隐藏委托类(房东)的实现;
优点二:可以实现客户与委托类(房东)间的解耦,在不修改委托类(房东)代码的情况下能够做一些额外的处理。

二  静态代理

2.1 静态代理

1.抽象出一个公共属性的接口A,并定义一个操作方法。

2.被代理对象或者叫委托对象(房东)、代理对象(中介)都要实现接口A

3.实例化一个被代理对象作为参数传入到代理对象的实例中,调用其动作方法(这里是sellHouse()方法)

4.静态代理是在编译期间就需要完成的,相当于每个类都要创建一个代理类,这样的代码冗余量很大。

2.1.1 创建一个卖房接口

public interface Seller 
    public void  sellHouse();

2.1.2 创建一个卖房实现类(房东)

package com.ljf.netty.proxy;

/**
 * @ClassName: FangDong
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/07/17 12:51:07
 * @Version: V1.0
 **/
public class FangDong implements Seller 
    private int money;
    public FangDong(int money) 
        this.money=money;
    
    @Override
    public void sellHouse() 
        System.out.println("我是房东,我卖的房子为:"+money+" 万!!!");
    

2.1.3 创建一个代理类(中介)

package com.ljf.netty.proxy;

/**
 * @ClassName: ZhongJIe
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/07/17 12:53:50
 * @Version: V1.0
 **/
public class ZhongJIe implements Seller 
    private Seller seller;

    public ZhongJIe(Seller seller) 
        this.seller = seller;
    

    @Override
    public void sellHouse() 
        System.out.println("我是中介,我在准备售前的事情");
        seller.sellHouse();
        System.out.println("我是中介,我在准备售后的事情=======");
    



2.1.4 创建一个客户端

package com.ljf.netty.proxy;

/**
 * @ClassName: TestStaticDynamic
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/07/17 12:57:48
 * @Version: V1.0
 **/
public class TestStaticDynamic 
    public static void main(String[] args) 
        Seller s=new FangDong(50);
        s.sellHouse();
        System.out.println("使用代理后:");
        Seller se=new ZhongJIe(s);
        se.sellHouse();
    

三  动态代理

3.1 动态代理

JDK提供的动态代理要求类实现invokationHandler接口,然后在运行时才去创建代理类,解决了静态代理代码冗余的问题。

1.抽象出一个公共属性的接口A,并定义一个操作方法。

2.被代理对象或者叫委托对象(房东)实现接口A

3.定义一个调用处理器类,这个类必须实现InvocationHandler接口,在这个实现类中就是要调用代理对象。调用代理类对象的方法时,这个“调用”会转送到invoke方法中,代理类对象作为proxy参数传入,参数method标识了我们具体调用的是代理类的哪个方法,args为这个方法的参数。

 4.客户端调用: 

创建委托,被代理对象(房东)

创建调用处理器对象, 处理所有的代理对象上的方法调用

创建一个代理对象,(中介)

调用代理的方法

 

3.1.1 创建一个卖房接口

public interface Seller 
    public void  sellHouse();

3.1.2 创建一个卖房实现类(房东)

package com.ljf.netty.proxy;

/**
 * @ClassName: FangDong
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/07/17 12:51:07
 * @Version: V1.0
 **/
public class FangDong implements Seller 
    private int money;
    public FangDong(int money) 
        this.money=money;
    
    @Override
    public void sellHouse() 
        System.out.println("我是房东,我卖的房子为:"+money+" 万!!!");
    

3.1.3 创建一个调用处理器类,这个类必须实现InvocationHandler接口,作为调用处理器,”拦截“对代理类方法的调用

package com.ljf.netty.proxy.dong;

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

/**
 * @ClassName: ZhongjieDynamicProxy
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/07/17 15:36:15
 * @Version: V1.0
 **/
public class ZhongjieDynamicProxy implements InvocationHandler 
    private Object obj; //obj为委托类对象;
    public ZhongjieDynamicProxy(Object obj) 
        this.obj = obj;
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        System.out.println("我是中介,我在准备售前的事情");
        Object result = method.invoke(obj, args);
        System.out.println("我是中介,我在准备售后的事情=======");
        return result;
    

3.1.4 创建客户端

package com.ljf.netty.proxy.dong;

import com.ljf.netty.proxy.FangDong;
import com.ljf.netty.proxy.Seller;

import java.lang.reflect.Proxy;

/**
 * @ClassName: TestDynamic
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2022/07/17 16:05:47
 * @Version: V1.0
 **/
public class TestDynamic 
    public static void main(String[] args) 
        //创建委托,被代理对象(房东)
        FangDong s=new FangDong(50);
        //创建调用处理器对象, 处理所有的代理对象上的方法调用
        ZhongjieDynamicProxy zdp=new ZhongjieDynamicProxy(s);
        //创建一个代理对象,(中介)
        Seller se=(Seller) (Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), zdp));
       //调用代理的方法
        se.sellHouse();
    

 https://www.jb51.net/article/86531.htm

Java动态代理 - 简书

以上是关于设计模式 2 代理模式-静态或者动态的主要内容,如果未能解决你的问题,请参考以下文章

08 设计模式 静态代理

JAVA基础——代理模式

设计模式之静态代理

设计模式之代理模式详解(java)

设计模式之代理模式详解(java)

Spring5一篇文章带你理解Spring5中的静态代理模式