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/