• 学习spring前,先了解了解代理模式


    什么是代理模式

    举个例子,我是一个包租公,我现在想卖房,但是我不想麻烦,每天被电话骚扰,所以这个时候我找了楼下一个中介,让他帮我代理这些事,那么他自然有租房的方法。以后如果有人想租房,直接找中介就行了。

    public interface Sale {
    	public void sale();
    }
    public class Jiajun implements Sale{
        public void sale() {
    		// TODO 自动生成的方法存根
    		System.out.println("jiajun要卖房");
    	}
    }
    public class SaleProxy implements Sale{
    
    	Jiajun jiajun=new Jiajun();
    	@Override
    	public void sale() {
    		// TODO 自动生成的方法存根
    		jiajun.sale();
    	}
    	
    }
    public Client{
        public static void main(String[] args)
        {
            Sale saleProxy=new SaleProxy();
    		saleProxy.sale();
        }
    }
    

    为什么用代理模式

    从上面的代码可以看出,代理类(SaleProxy)和真实类(Jiajun)好像没什么区别,我直接(new Jiajun().sale())不就行了,那么为什么多次一举呢,任何设计都有他的好处。我们可以发现代理类可以在真实类的基础上增加方法,比如这个时候中介可以收取买主的费用。

    public class SaleProxy implements Sale{
    
    	Jiajun jiajun=new Jiajun();
    	@Override
    	public void sale() {
    		// TODO 自动生成的方法存根
    		charge();
    		jiajun.sale();
    	}
    	public void charge()
    	{
    	    System.out.println("jiajun要卖房,中介要收费");
    	}
    	
    }
    

    而这个不关我事,中介你帮我租出去就行。

    什么是动态代理模式

    静态代理模式有他的缺点:

    • 如果这个时候,我要做的事情增多了,比如我在卖房的时候,我还可以租房。那么我在Sale接口要增加一个方法,真实类(Jiajun)要实现多一个方法,此时代理类(SaleProxy)又要实现多一个方法,如果以后要拓展,会增加很多方法,那么就增加维护难度。
    public interface Sale {
    	public void sale();
    	public void rent();
    }
    public class SaleProxy implements Sale{
    
    	Jiajun jiajun=new Jiajun();
    	@Override
    	public void sale() {
    		// TODO 自动生成的方法存根
    		jiajun.sale();
    	}
    	public void rent()
    	{
    		jiajun.rent();
    	}
    }
    
    • 如果真实类(Jiajun)实现了多个接口,我要为多种方法代理,那么我要手动创建很多代理类。
      比如这里我实现了两个接口。
    public interface Sale {
    	public void sale();
    }
    
    public interface Buy {
    	public void buy();
    }
    public class Jiajun implements Sale,Buy{
    
    	public void sale() {
    		// TODO 自动生成的方法存根
    		System.out.println("jiajun要卖房");
    	}
    	public void buy() {
    		// TODO 自动生成的方法存根
    		System.out.println("jiajun要买房");
    	}
    }
    

    这个时候我要生成两个代理,那么我就要创建两个代理类

    public class BuyProxy implements Buy{
    
    	Jiajun jiajun=new Jiajun();
    	public void buy() {
    		// TODO 自动生成的方法存根
    		jiajun.buy();
    	}
    
    }
    public class SaleProxy implements Sale{
    
    	Jiajun jiajun=new Jiajun();
    	@Override
    	public void sale() {
    		// TODO 自动生成的方法存根
    		jiajun.sale();
    	}
    	
    }
    public class Client {
    	public static void main(String[] args) {
    		
    		Sale saleProxy=new SaleProxy();
    		saleProxy.sale();
    		Buy buyProxy=new BuyProxy();
    		buyProxy.buy();
    
    	}
    }
    
    

    如果我要为多种方法代理,那么就会产生很多代理类。

    针对这些缺点,动态代理出现了

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyHandler implements InvocationHandler{
    
    
    		private Object tar;
    
    	    //绑定委托对象,并返回代理类
    		public Object bind(Object tar)
    		{
    			this.tar=tar;
    			//绑定该类实现的所有接口,取得代理类
    			return Proxy.newProxyInstance(tar.getClass().getClassLoader(), tar.getClass().getInterfaces(), this);
    		}
    
    	    public Object invoke(Object proxy , Method method , Object[] args)throws Throwable
    	    {
    	        Object result = null;
    	        result = method.invoke(tar,args);
    	        return result;
    	    }
    
    }
    public class Client {
    	public static void main(String[] args) {
    
    		
           ProxyHandler proxy = new ProxyHandler();
           //绑定该类实现的所有接口
           Sale saleProxy = (Sale) proxy.bind(new Jiajun());
           saleProxy.sale();;
           
           Buy buyProxy=(Buy)proxy.bind(new Jiajun());
           buyProxy.buy();
    
    	}
    }
    

    显然,上面的缺点得到解决了。

    • 即使接口增加方法,我也不用在代理类再实现一次。
    • 即使我要对不同方法做代理,我也不用创建一个代理类文件。
    • 动态代理类由Java反射机制动态生成,不用我们自己生成(这里我们并没有看到买房代理类,卖房代理类文件)
    • 动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。(我们要买房代理就买房代理,卖房代理就卖房代理,比较灵活)。
    • 总的来说,关键的就是我们避免了代理类文件的编写,从而提高了许多便利。
    • 动态代理的实现:jdk代理和cglib代理

    我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

  • 相关阅读:
    table 如何不越过父级div
    sqlite3_column_type 与 SQLITE_NULL的区别
    lua 协程的理解
    linux 信号
    linux 查看文件夹大小
    linux 僵屍进程
    软件架构的理解
    jquery正则表达式
    linux C遍历目录下文件
    linux 进程间同步互斥
  • 原文地址:https://www.cnblogs.com/-new/p/6871579.html
Copyright © 2020-2023  润新知