本文用jdk动态代理模拟了spring的AOP的实现技术
AOP面向切面编程,可用于权限验证,效率检查,事务,异常管理等
JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中 InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,在并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一 起。
而Proxy为InvocationHandler实现类动态创建一个符合某一接口的代理实例
UserDAOImpl.java
public class UserDAOImpl implements UserDAO {
public void save(User user) { System.out.println("user saved!"); } public void delete() { System.out.println("user deteleted"); }}LogInterceptor.java//处理程序必须实现InvocationHandler接口
public class LogInterceptor implements InvocationHandler {
private Object target; //被代理的对象 public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public void beforeMethod(Method m) { System.out.println(m.getName() + " start"); }/* proxy是代理实例,一般不会用到;method是代理实例上的方法,通过它可以发起对目标类的反射调用;
* args是通过代理类传入 的方法参数,在反射调用时使用 * */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { beforeMethod(m); m.invoke(target, args); return null; }}UserServiceTest.java
public void testProxy() {
UserDAO userDAO = new UserDAOImpl(); LogInterceptor li = new LogInterceptor(); //创建一个Handerler对象 li.setTarget(userDAO); //将Handler对象和被代理对象关联 /*newProxyInstance参数含义 * 第一个参数:代理的类加载器,必须和被代理的对象是一个类加载器 * 第二个参数含义:代理对象要实现的那些接口 * 第三个参数:指派方法调用的调用处理程序 * */ UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li); System.out.println(userDAO.getClass().getInterfaces().getClass()); System.out.println(userDAOProxy.getClass().getInterfaces()[0]); userDAOProxy.delete(); userDAOProxy.save(new User()); }
运行结果:
interface com.bjsxt.dao.UserDAO
delete startuser deteletedsave startuser saved!