Spring AOP JDK動態代理
在沒有使用Spring之前,如果要對DAO層進行修改,比如說做數據安全性驗證。那麼,就需要對DAO層中的每一個方法都進行修改,項目小了好說,大了的話呢?不久後又要刪掉這一功能呢?那豈不又是費神之事。
這一問題使用AOP(Aspect Oriented Programming 面向切面編程)就好解決的多了。面向切面編程,就像使用FilterServlet(過濾器)對字符編碼進行轉換時一樣。當BIZ層調用DAO層中的方法時,可以對其實施攔截,在之前或之後插入所要執行的操作。
下面看看具體如何對這一問題進行應用。首先創建一個安全性檢測類SecurityHandler並讓它實現InvocationHandler接口。聲明一個Object類型的變量用於存儲目標對象(我們要對誰進行攔截)。提供一個方法getProxy(),該方法接收目標對象然後返回該對象的代理對象。在invoke()方法中先進行數據安全性檢測,然後再調用目標對象的方法。因爲無法確定所調用的方法是或否有返回值,所以默認的令其返回Object類型。完整代碼如下:
Java 代碼複製代碼
package cn.ineeke.spring;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class SecurityHandler implements InvocationHandler {
//用於存儲目標對象
private Object obj;
//獲得目標對象的代理
public Object getProxy(Object obj){
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
this);
}
//方法調用
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
printSomthing();
Object ret = null;
try {
ret = method.invoke(this.obj, args);
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
private void printSomthing(){
System.out.println("--------Security----------");
}
}
接下來編寫一個測試類。
Java 代碼複製代碼
package cn.ineeke.spring;
public class Client {
public static void main(String[] args) {
SecurityHandler sryHandler = new SecurityHandler();
IUserDAO userDAO = (IUserDAO) sryHandler.getProxy(new UserDAOImpl());
userDAO.getUser();
}
}
上面的代碼中,首先創建了一個SecurityHandler的實例sryHandler,然後調用getProxy()方法根據具體的目標對象創建具體的代理對象,最後通過代理來調用相關的方法。這麼一來,無論是開發階段還是後期的維護中,如果需要改動,則只需要改動SecurityHandler類即可,不再需要對DAO中每個方法逐一改動了。
本文來源於Neeke's Blog http://www.ineeke.cn/ , 原文地址:http://www.ineeke.cn/archives/Spring-AOP-JDK-DynamicProxy/