代理模式

一、静态代理

<span style="font-size:18px;">public interfaceUserManager {
   public void addUser(StringuserId,String userName);
  
   public void delUser(String userId);
  
   public String queryUser(StringuserId);
  
   public void updateUser(StringuserId,String userName);
  
}
 
 
public classUserManagerImpl implements UserManager {
 
   @Override
   public void addUser(String userId,String userName) {
//    System.out.println("start---->addUser");
//    try{
//       System.out.println("UserManagerImpl---->addUser"+userId);
         System.out.println("success---->addUser");
//    }catch(Exceptione){
//       e.printStackTrace();
//       System.out.println("error---->addUser");
//       thrownew RuntimeException();
//    }
     
 
   }
 
 
   @Override
   public void delUser(String userId){
//    System.out.println("start---->delUser");
//    try{
//       System.out.println("UserManagerImpl---->delUser"+userId);
         System.out.println("success---->delUser");
//    }catch(Exceptione){
//       e.printStackTrace();
//       System.out.println("error---->delUser");
//       thrownew RuntimeException();
//    }
     
 
   }
 
  
   @Override
   public String queryUser(StringuserId) {   
        
         System.out.println("UserManagerImpl---->queryUser"+userId);
         return "张三";
  
     
   }
 
   @Override
   public void updateUser(StringuserId, String userName) {
      System.out.println("UserManagerImpl---->updateUser"+userId);
   }
 
}
 
 
public classUserManagerImplProxy implements UserManager {
   private UserManager userManager;
   publicUserManagerImplProxy(UserManager userManager){
     
      this.userManager=userManager;
   }
 
 
   @Override
   public void addUser(String userId,String userName) {
      System.out.println("start---->addUser");
      try{
         System.out.println("UserManagerImpl---->addUser"+userId);
         userManager.addUser(userId,userName);
      }catch(Exception e){
         e.printStackTrace();
         System.out.println("error---->addUser");
         throw new RuntimeException();
      }
     
 
   }
 
  
   @Override
   public void delUser(String userId){
     
      System.out.println("start---->delUser");
      try{
         System.out.println("UserManagerImpl---->delUser"+userId);
         userManager.delUser(userId);
      }catch(Exception e){
         e.printStackTrace();
         System.out.println("error---->delUser");
         throw new RuntimeException();
      }
   }
 
  
   @Override
   public String queryUser(StringuserId) {
      StringuserName="";
      try{
         System.out.println("start---->queryUser");
         userName=userManager.queryUser(userId);
         System.out.println("sucess---->queryUser");
      }catch(Exception e){
         e.printStackTrace();
         System.out.println("error---->queryUser");
         throw new RuntimeException();
      }
      return userName;
   }
 
  
   @Override
   public void updateUser(StringuserId, String userName) {
      System.out.println("start---->updateUser");
      try{
         System.out.println("UserManagerImpl---->updateUser"+userId);
         userManager.updateUser(userId,userName);
      }catch(Exception e){
         e.printStackTrace();
         System.out.println("error---->updateUser");
         throw new RuntimeException();
      }
   }
 
}
 
public classClient {
 
   /**
    * 函数功能说明
    * v-huxj  2015-5-27
    * @参数:@param args   
    * @return void  
    * @throws
    */
 
   public static void main(String[] args) {
      UserManageruserManager=newUserManagerImplProxy(new UserManagerImpl());
      StringuserName=userManager.queryUser("0001");
      System.out.println(userName);
   }
 
}
 </span>

以上是静态代理模式,代理类目标类实现共同的接口,他们对接口中的方法进行了重写。从代码中来看,代理类的重写的方法实现其实是调用了目标类的实现方法。所以代理其实起到一个中介的作用,代理类是帮目标类做事的。

代理的好处:

a)  为其他对象提供一种代理以控制对这个对象的访问,使得目标类的封装性得到保障。

b) 代理可以使这个对象的业务逻辑更加纯粹(可以抽出与业务逻辑无关的服务)。

 

但是静态代理也暴露出它的不足:

a)静态代理只能服务于特定的接口

b)静态代理的代理类必须要一一实现接口里的方法,一一调用目标类的方法。这样一来,如果目标方法足够多,代码量足够大,重复比较多。特别是操难免会出失误。

综上,它的缺点就比较突出。


接下来我们引出了,动态代理类,接下来看它是如何解决我们的问题的。


二、动态代理


通过图中的LogHandler它是程序运行时,加载上对应的UserManagerImpl和接口类类的,

<span style="font-size:18px;">public classLogHandler implementsInvocationHandler {
  
   //实际的对象
   private Object targetObject;
   //获取代理类
   public ObjectnewProxyInstance(Object targetObject){   
      this.targetObject=targetObject;
      return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(), this);
 
   }
 
   @Override
   public Object invoke(Objectproxy, Method method, Object[] args)
         throws Throwable {
      System.out.println("start--->"+method.getName());
      for(int i=0;i<args.length;i++){
         System.out.print(args[i]+"  ");
      } 
      Objectret=null;
      try{
         ret=method.invoke(targetObject, args);
         System.out.println("success--->"+method.getName());
      }catch(Exception e){
         e.printStackTrace();
         System.out.println("error--->"+method.getName());
         throw new RuntimeException();
        
      }
      return ret;
   }
 
}
 
 
public classClient {
 
   /**
    * 函数功能说明
    * v-huxj  2015-5-27
    * @参数:@param args   
    * @return void  
    * @throws
    */
 
   public static void main(String[] args) {
      LogHandlerlogHander=newLogHandler();
      UserManageruserManager=(UserManager) logHander.newProxyInstance(new UserManagerImpl());
      System.out.print(userManager.queryUser("0001"));
   }
 
}
 </span>


动态代理类,自定义一个类实现InvocationHandler接口,通过Proxy.newProxyInstance(loader,interfaces, h)来拿到代理,通过实现InvocationHandler接口的 invoke(Objectproxy, Method method, Object[] args)方法,即可实现代理的类的所有操作。而且是在运行时,将代码横切过去,运行的。这样的话,代码比较简洁,操作比较灵活,效率比较高。

 

总结:

动态代理类正好弥补了静态代理的不足,第一:它是面向的接口,是由你传过来的目标类所决定的。第二:一份代码,在程序运行的时候切入到代码中的的。

心得:当遇到不美好的时候,我们要选择不抛弃,想办法,事物一定会变的而很美好。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值