代理模式总结笔记

代理模式

代理模式定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用

举三个例子:

​ 1:支付宝付款,我们平时付款只要知道付多少钱就行,至于从哪张银行卡上扣钱,由Ali负责

​ 2:结婚时,你只需要和新娘结婚就行,至于布置婚礼场所可以由婚办公司去布置

​ 3:中介,房东出租房子,需要把自己要出租的房子交给中介,让他去出租

  • spring Aop的底层实现是代理模式(动态代理)

    在这里可以考虑下多线程里thread(new thread1()).start()是代理?以及IO中的BufferedReader(FileBufferedReader())是代理?如果不是它们又是什么?

    4:代理模式分类:

    • 静态代理

    • 动态代理

      静态代理:

​ 静态代理有4个角色:

  • 抽象角色: 一般会使用接口或者抽象类去解决

  • 真实角色:被代理的对象

  • 代理角色:代理真实角色,代理真实角色后,一般会做一些附属操作

  • 客户:访问代理对象的人

    下面代码以中介为例子(没有写客户,因为客户和房东性质差不多,客户找房子也要去找代理):

    先分析

    抽象角色:出租房接口

    public interface Rent {
      
    	public void rent();
    	
    }
    

    真实角色:房东类(实现出租房这个接口)

    public class Host implements Rent{
    	@Override
    	public void rent() {
    		// TODO Auto-generated method stub
    		System.out.println("房东要出租房子");
    	}
    

    代理角色:

    public class Proxy implements Rent{
      private Host host;
      
    
    public Proxy(Host host) {
    	this.host = host;
    }
    
    @Override
    public void rent() {
    	// TODO Auto-generated method stub
    	host.rent();
    	fare();
    	house();
    }
    //以下是中介附属的方法,人家不可能无缘无故帮你做的
     public void fare(){
    	 System.out.println("收代理费");
     }
     public void house(){
    	 System.out.println("去看房东要出租的房子");
     }
    
    }
    

    ​ main类

    public class Main {
    
    	/**
    	* @Title: main
    	* @Description: TODO
    	* @param @param args
    	* @return void
    	* @throws
    	*/
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    //房东要出租房子,但找不到租房子的人,只能交给代理去做
    		Host host=new Host();
    //帮房东赵租房子的人,但会带一些附属操作,人家不可能无缘无故帮你的
           Proxy px=new Proxy(host);
            px.rent();
    	}
    

    main方法里也可以用匿名对象写,就像我上面写的多线程那个对象

    动态代理:

    动态代理依靠反射包下(InvocationHandler,proxy)来动态生成一个动态代理类生成的,不是像静态代理那样去直接写好的

    invocationHandler(是一个接口):是由代理实例调用处理程序实现的接口(类似于上面静态里的出租房子那个接口,只是这个接口中有invoke方法,里面利用反射机制,将里面的成分反射成相应的类)

    proxy:提供了创建动态代理类和实例的静态方法

    每个代理实例都有一个关联的调用程序接口,当在代理实例上调用方法时,方法调用将被编码分配到其调用处理程序的invoke()方法

    动态代理分为两大类:基于接口动态代理和基于类的动态代理

    基于接口:依赖于jdk

    基于类:cglib

    角色和静态代理角色一样

    代码演示:

    抽象角色:出租房子接口

    public interface Rent {
    	public void rent();
    }
    

    产生代理类的类(动态代理类的对象是抽象透明的,因为本身代理类都是靠里面反射机制产生的):

    public class ProxyInvocationHandler implements InvocationHandler{
       //被代理的接口
    	private Rent rent;
    	
    	public void setRent(Rent rent){
    		this.rent=rent;
    	}
    	
    	//生成得到代理类
    	public Object getProxy(){
    	return 	Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
    	}
        
    //处理代理实例并返回结果
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		// TODO Auto-generated method stub
    		//利用反射机制实现
    	Object result=method.invoke(rent, args);
    	return result;
    	
    	}
        
    

    main类

    public class Main {
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		//真实角色
            Host host=new Host();
            //通过调用程序处理角色来处理我们要调用的接口对象
            ProxyInvocationHandler pih=new ProxyInvocationHandler();
            pih.setRent(host);
        /* Proxy.newProxyInstance(this.getClass().getClassLoader(), 
        rent.getClass().getInterfaces(), this);*/
        //getProxy()方法这里有我们的代理的接口,和可以产生代理类的类 
            Rent proxy=(Rent)pih.getProxy();
            proxy.rent();   
    	}
    }
    
    静态代理优点:

    便于简单业务操作,扩展原功能,不侵入源代码

    缺点:

    容易出现代码冗余,开发效率降低,不利于维护

    静态代理与动态代理比较

    动态代理比较好,它不仅基本上拥有静态代理的优点,

    一个动态代理类可以代理多个真实类pih.setRent(host),只要把里面对象换了便可,但要实现同一个接口

posted @   易言之  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示