前言
Spring的两大核心之一的AOP就是基于动态代理实现的,这里主要记录一下JDK的动态代理。CGLIB另说。
一、什么是代理?
代理其实是程序的一种设计模式。主要是为了给其他对象提供一种代理来控制对这个对象的访问。
举个例子:代购,大家都知道,我身在国内不方便或没时间出国,但是我想购买国外的一些产品,于是我委托代理人去帮我购买。
代理也是一样,我这个对象不适合或不能直接去访问另一个对象,我就需要一个代理来帮我访问这个对象。
二、什么是动态代理?
动态代理:程序运行之前并没有设定好谁要用代理,只是运行时候,对象想要访问某些对象不方便时候,对其动态的生成那些对象的代理对象。
三、JDK动态代理:
jdk动态代理的核心是Proxy,所以主要讲述一下Proxy怎么实现动态代理的。
newProxyInstance:
这是自己实现的获取JDK代理对象的方法,其实就调用了一下Proxy.newProxyInstance方法
**该方法的入参:**目标类的类加载器、目标类实现的接口、以及一个调用处理器InvocationHandler(说白了就是你要干的事)
**该方法的返回:**返回目标类的代理对象
/**
* 获取jdk代理对象
* @return
*/
public Object getProxyInstance(){
return Proxy.newProxyInstance(targetClass.getClassLoader(), targetClass.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//拦截到的方法是不是要代理的目标方法名
if(methodName.equals(method.getName())){
// //调用目标对象的目标方法
// ProceedingJoinPoint joinPoint = new ProceedingJoinPoint(method,targetObject,args);
// //aop所在切面类的对象和参数
// return aopMethod.invoke(aopClass.newInstance(),joinPoint);
//拦截到的方法是要代理的目标方法名
//方法处理前
Object obj = method.invoke(targetObject,args);
//方法处理后
return obj;
}else {
//拦截到的方法不是要代理的目标方法名
return method.invoke(targetObject,args);
}
}
});
}
InvocationHandler:
调用处理器,可以在这个里面的invoke方法对代理到的方法进行处理,我这里是简单的实现AOP,所以代理指定的方法,其余的方法跳过(不是不执行,只是不加任何前置处理或后置处理)
InvocationHandler也有三个参数:分别代表代理类实例、被调用方法、调用的参数。
总结:
看到这里其实就应该明白AOP为啥用动态代理了,因为代理不仅仅可以访问对象调用方法,还可以在原有方法的基础上,做增强处理即前置处理后置处理,比如实现,前置处理与数据库建立连接,后置处理与数据库建立的连接关闭,再比如操作前,进行权限认证,操作后进行统一的结果封装,或统一的异常捕获处理等待,这就是AOP强大功能的基础。
PS:JDK动态代理的核心是Proxy,所以注定了动态生成的代理类有一个共同的父类Proxy,这也就导致了JDK动态代理只能支持interface接口,那么为了实现对class动态代理的支持,所以有一个叫做cglib的东西出现了。