Spring AOP之 java 动态代理(Proxy 与 InvocationHandler)理解

   在学习spring的过程当中,了解到一个很重要的java编程思想,就是面向切面的编程(aop)。什么是面向切面的编程呢?对于这个概念我在网上查了,获得以下的答案:
java

   AOP(Aspect-Oriented Programming,面向切面的编程),它是能够经过预编译方式和运行期动态代理实现在不修改源代码的状况下给程序动态统一添加功能的一种技术。它是一种新的方法论,它是对传统OOP编程的一种补充。spring

   概念性的东西比较死,关键是要理解其中的原理。看下图所示:数据库

   当你有一个写好的方法,想要在其调用的前面或者后面加上一些记录日志或别的一些逻辑,但又不想更改(或者不能改)原有的代码时,AOP就能发挥它极大的优点了。接下来看看使用Proxy和 InvocationHandler是如何实现的。编程

public interface UserDao {
    public void save(User user) ;
}
//定义一个保存User对象到数据库的接口
                                                                                                                                                                                               


public class UserDaoImpl implements UserDao {
    @Override
    public void save(User user) {
        System.out.println("user saved!");
    }
}
//接口的实现

   

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//编写切面逻辑类,必需要实现InvocationHandler 接口
public class DebugInterceptor implements InvocationHandler {
    private Object target;
    public Object getTarget() {
        return target;
    }
    public void setTarget(Object target) {
        this.target = target;
    }
                                                                                                                                                                                           
    //须要插入的逻辑
    private void before(Method m) {
        System.out.println(m.getName() + " start!");
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        before(method);
        method.invoke(target, args);//使用java反射调用代理方法
        return null;
    }
}


   使用Junit4写了个单元测试,测试代理方法。调用Proxy类的静态方法newProxyInstance(classloader,interfaces,handler)产生代理对象。代理对象与被代理对象实现了同一个接口UserDao,因此能调用其中的save方法。框架

public class ProxyTest {
    @Test
    public void testProxy() {
        UserDao userDao = new UserDaoImpl();
        DebugInterceptor di = new DebugInterceptor();
        di.setTarget(userDao);
        UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
                userDao.getClass().getInterfaces(), di);
        userDaoProxy.save(new User());
    }
}


  测试结果 ide

       save start!性能

       user saved!单元测试

   成功将切面逻辑加入到方法调用以前,嘿嘿。
学习

   到此,Proxy与InvocationHandler实现动态代理的实现过程就搞定了。java动态代理不仅有这一个方法,还能用CGlib,CGlib是一个强大的,高性能,高质量的代码生成类库,这里就很少作介绍了,你们能够到网上本身查。测试

   还有spring的AOP实现的动态代理不仅是这样子,它使用aspectJ这个切面框架。具体的等之后再继续说吧。继续研究。。。

   最后,发现本身写得好少,也存在不少不足,欢迎你们指点与吐槽。

   在交流中成长。