java代理模式案例解析

146 阅读3分钟

1.什么是代理模式:

举个生活中的例子,房东有房子想要出租,又觉得和租客打交道麻烦,接待待租的人也很浪费时间,于是把房子交给中介,自己只管收租。

简单的说,代理模式就是用代理类来对另外一个不能直接访问的对象进行增强处理

我们把这个案例用静态代理和动态代理方式分别实现一遍:

1.1静态代理

  /**  * 静态代理接口  */  
public interface LandlordService {   
   void receiveMoney(String name);  
}  ​

/**  
* 房东类  
*/  
public class LandLord implements LandlordService {
    @Override      
    public void receiveMoney(String name) {
          System.out.println("房东对"+name+"收租");      
    } 
}  ​  

/**  
* 静态代理对象  
*/  
public class StaticHouseAgent implements LandlordService{
    private LandLord landLord;  ​      
    public StaticHouseAgent(LandLord landLord) { 
         this.landLord = landLord;      
    }    

     /**      
    * 代理和被代理对象使用相同的方法,在代理方法内调用被代理对象的方法,并在执行前后做一些处理      
    */      
    @Override      
    public void receiveMoney(String name) {
            System.out.println("有人来租房子了 ---");          
            System.out.println("来租房子的人叫:" + name); 
            landLord.receiveMoney(name);
            System.out.println("租房完成,我把房子交给租客 ---");
     }  
}  ​  

public class StaticProxyApp {  ​      
    public static void main(String[] args) {         
            LandLord landLord = new LandLord();          
            StaticHouseAgent staticHouseAgent = new StaticHouseAgent(landLord);
            staticHouseAgent.receiveMoney("张三");
      }  
}  ​  

打印结果如下:  ​  
有人来租房子了 ---  
来租房子的人叫:张三  
房东对张三收租  
租房完成,我把房子交给租客 ---

1.2动态代理:java的Proxy实现

/**  
* proxy代理对象需要实现一个接口,后续生成的代理类通过这个接口来知道有哪些方法  
*/  
public interface LandlordService {      
    void receiveMoney(String name);  
}  ​  

/**  
* 房东类  
*/  
public class LandLord implements LandlordService {      
    @Override      
    public void receiveMoney(String name) {
          System.out.println("房东对"+name+"收租");      
    }  
}  ​  

/**  
* 房屋中介类  
*/  
public class HouseAgent implements InvocationHandler {
        private LandLord landLord;  ​      
        public HouseAgent(LandLord landLord) { 
             this.landLord = landLord;      
        }         

        /**       
        *  代理对象实际上执行的是这个方法,我们可以在这个方法里对要代理的对象进行方法增强,举例如下:       
        *  1.在方法执行前,日志记录方法的参数,或者对进入方法的参数进行处理(加密、解密)       
        *  2.在方法执行后,日志记录方法调用结束,或者记录执行结果       
        *        
        * @param proxy 被代理对象       
        * @param method 正在执行的方法       
        * @param args  调用正在执行的方法需要的参数       
        * @return       
        * @throws Throwable       
        */      

        @Override      
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              System.out.println("有人来租房子了 ---");          
              System.out.println("来租房子的人叫:" + Arrays.toString(args));    
              //真正执行被代理对象的方法          
              Object invoke = method.invoke(landLord, args);   
              System.out.println("租房子完成了,我把房子交给租客 ---");        
              return invoke;     
        }   
}  ​ 

/**  
* main方法运行  
*/  
public class ProxyApp {  ​      
    public static void main(String[] args) {          
        LandLord landlord = new LandLord();          
        HouseAgent houseAgent = new HouseAgent(landlord);          
        LandlordService o = (LandlordService)Proxy.newProxyInstance(LandLord.class.getClassLoader()
                  , new Class[]{LandlordService.class},
                  houseAgent);         
         //通过代理对象(houseAgent),对Landlord方法进行了增强 
         o.receiveMoney("张三");      
    }  
}  ​  

打印结果如下:  ​  
有人来租房子了 ---  
来租房子的人叫:张三  
房东对张三收租  
租房完成,我把房子交给租客 ---

2.总结:可以看出,代理模式不用直接访问被代理对象,而是通过代理类对象来调用被代理对象的方法,并在方法的执行前后进行一些前序和后续处理