1. 程式人生 > >spring 基於AOP模擬許可權檢查

spring 基於AOP模擬許可權檢查

一、基於jdk動態代理模擬許可權檢查

1.JDKProxy.java

public class JDKProxy implements InvocationHandler {

    private Object targetObject;//需要代理的目標物件
    /*
     * 建立動態代理,通過反射來例項化目標物件
     */
    public Object newProxy(Object targetObject) {//將目標物件傳入進行代理
        this.targetObject = targetObject;
       /* (被代理物件的類載入器,被代理物件所有的類介面,被代理物件)*/
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(), this);//返回代理物件
    }

    /*
     *反射知識
     *invoke(代理的真實物件、代理的方法、方法中接收的引數)
     *invoke:簡單理解就是在不知道物件的前提下,通過配置的引數來呼叫方法。
     */
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
        //一般我們進行邏輯處理的函式比如這個地方是模擬檢查許可權
                checkPopedom();
        Object ret = null;// 設定方法的返回值
        ret  = method.invoke(targetObject, args); 
       //呼叫invoke方法,通過反射機制來執行目標物件的方法,賦值給ret
        return ret;
    }

    private void checkPopedom() {//模擬檢查許可權的例子
        System.out.println("JDK動態代理類 檢查許可權  checkPopedom()!");
    }
}

2.UserManager.java

public interface UserManager {
  public void addUser(String id, String password);
  public void delUser(String id);
}
public class UserManagerImpl implements UserManager {
  public void addUser(String id, String password) {
      System.out.println("掉用了UserManagerImpl.addUser()方法! ");

  }
  public void delUser(String id) {
      System.out.println("掉用了UserManagerImpl.delUser()方法! ");

  }
}

3.測試類

public class Client {
    public static void main(String[] args) {
        System.out.println("-----------JDKProxy-------------");
        JDKProxy jdkPrpxy = new JDKProxy();
        UserManager userManagerJDK = (UserManager) jdkPrpxy.newProxy(new UserManagerImpl());//建立動態代理物件
        userManagerJDK.addUser("tom", "root");//呼叫方法前先呼叫revoke方法
    }

}

二、cglib實現

1.CGLibProxy.java

public class CGLibProxy implements MethodInterceptor {

    private Object targetObject;// CGLib需要代理的目標物件

    public Object createProxyObject(Object obj) {
        this.targetObject = obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        Object proxyObj = enhancer.create();
        return proxyObj;// 返回代理物件
    }

    /*
     *invoke()呼叫類中的方法
     *
     */
    public Object intercept(Object proxy, Method method, Object[] args,
            MethodProxy methodProxy) throws Throwable {
        Object obj = null;
        if ("addUser".equals(method.getName())) {// 過濾方法
            checkPopedom();// 檢查許可權
        }
        obj = method.invoke(targetObject, args);
        return obj;
    }

    private void checkPopedom() {
        System.out.println("呼叫CGLib進行檢查許可權  checkPopedom()!");
    }
}

2.測試程式碼

public class Client {

    public static void main(String[] args) {
    	UserManager userManager = (UserManager) new CGLibProxy().createProxyObject(new UserManagerImpl());
        System.out.println("-----------CGLibProxy-------------");
        //呼叫方法前先呼叫revoke方法
        userManager.addUser("tom", "root");
    
    }

}

總結:每次執行方法前都會呼叫檢查許可權那個方法。