`
蓝色的墨
  • 浏览: 76662 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

由一个小问题----静态代理---动态代理.

阅读更多

场景描述: 假设我们有一个实现类- userManager ,  这个实现类有很多方法(增删改查).现在需求发生了改变,当我们调用这个类里面的方法的时候,我们要检查一下,你有没有权利调用这些方法.

原接口:userManager

     package com.fd;

public interface UserManager {

public void addUser(String username ,String password);

   public void delUser(int userId);

   public String findUser(int userId);

   public void modifyUser(int userId , String username ,String password);

}

原接口实现:userManagerImpl

   package com.fd;

public class UserManagerImpl implements UserManager {

   public void addUser(String username, String password) {

     System.out.println("addUser");

   }

   public void delUser(int userId) {

     System.out.println("delUser");

   }

   public String findUser(int userId) {

     System.out.println("findUser");

     return "张三";

   }

   public void modifyUser(int userId, String username, String password) {

     System.out.println("modifyUser");

   }

}

现在需求变化,要在调用每一个方法之前,你都要检查一下是否有权限调用这些个方法.

原接口不变

原来的实现类要改变,当然我们不希望改变,我们都知道设计程序的一些原则:”对扩展开放,对修改关闭”.

那么由于需求的变化,我们现在的实现类要修改.(假如实现类中有很多方法的话,那就更痛苦了.)

package com.fd;

public class UserManagerImpl implements UserManager {

   public void addUser(String username, String password) {

     checkSecurity();

     System.out.println("addUser");

   }

   public void delUser(int userId) {

     checkSecurity();

     System.out.println("delUser");

   }

   public String findUser(int userId) {

     checkSecurity();

     System.out.println("findUser");

     return "张三";

   }

   public void modifyUser(int userId, String username, String password) {

     checkSecurity();

     System.out.println("modifyUser");

   }

  

    public void checkSecurity(){

      System.out.println("----------checkSecurity-----------");

    }

}

我们在其中加了一个权限检查的方法,而且,在实现类里面的每个方法里面都调用了一次.太麻烦了.而且容易出问题.

那现在我们使用静态代理. 保持原来的实现类不变.多加一个类,同样实现接口UserManager.再加上权限检查的方法.加上一个UserManager的引用.这样让它在执行的时候,去调用这个代理类,如果它有这个权限的话,再让它去调用真正实现类的方法.代码如下.

package com.fd;

public class UserManagerImplProxy implements UserManager {

   private UserManager userManager;

   public void addUser(String username, String password) {

     checkSecurity();

     userManager.addUser(username, password);

   }

   public void delUser(int userId) {

     checkSecurity();

     userManager.delUser(userId);

   }

 

   public String findUser(int userId) {

     checkSecurity();

     return userManager.findUser(userId);

   }

   public void modifyUser(int userId, String username, String password) {

     checkSecurity();

     userManager.modifyUser(userId, username, password);

   }

   public void checkSecurity() {

     System.out.println("----------checkSecurity-----------");

   }

}

这样一来,好处就是,原来的程序保持不变,仅仅扩展了一个类.就算出了问题,也好定位.但是,在调用它的方法之前,同样都要先调用同一个方法,就像一个独立的服务.我们可以单独的把它剥离出来.什么时候想加,就加上,想去掉,很轻松的就去掉了.那就看看我们的动态代理.面向接口编程.让目标和代理共同实现一个接口.

动态代理类SecurityHandler

package com.fd;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

public class SecurityHandler implements InvocationHandler {

   private Object targetObject;

   public Object createProxyInstance(Object targetObject) {

     this.targetObject = targetObject;

     return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),

          targetObject.getClass().getInterfaces(), this);

 

   }

   @Override

   public Object invoke(Object proxy, Method method, Object[] args)

        throws Throwable {

     checkSecurity() ;

     Object ret = method.invoke(targetObject, args);

 

     return ret;

   }

 

   public void checkSecurity() {

     System.out.println("----------checkSecurity-----------");

   }

 

}

 

客户端代码

package com.fd;

public class Client {

   public static void main(String[] args){

     SecurityHandler handler = new SecurityHandler();

     UserManager userManager = (UserManager)handler.createProxyInstance(new UserManagerImpl());

     userManager.addUser("张三", "123");

     userManager.delUser(1);

     userManager.findUser(2);

     

   }

}

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics