前言
动态代理的作用和本质是拦截器,和servlet的拦截器、spring的mvc 控制器拦截器和aop拦截器是一样的作用。
只不过不同拦截器的底层实现不一样,aop拦截器就是基于jdk动态代理。
jdk动态代理有2种实现方法
1.jdk自带的动态代理
必须是接口
2.第三方库cglib
支持非接口,即实现类
demo
总共有3个类
接口
目标类的接口
package proxy;
/**
* 目标类的接口,jdk动态代理的类一定要实现某一个接口
*/
public interface User {
void sayHello();
}
实现类
目标类的实现类
package proxy;
/**
* 目标对象的具体类
*/
public class UserImpl implements User {
@Override
public void sayHello() {
System.out.println("hello");
}
}
拦截器
1.如何使用?
拦截器类需要继承InvocationHandler。
2.实现代码
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 每个代理对象 内部都有一个实现了InvocationHandler接口的 类的实例
*
* InvocationHandler 顾名思义就是 代理对象的方法调用的处理类(调用它的invoke方法)
*
*/
public class InvocationHandlerImpl implements InvocationHandler {
// 目标对象
private Object target; //接口实现类
public InvocationHandlerImpl(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 代理方法简单地打下日志,这其实就是spring aop的简单实现
System.out.println("start");
// 调用目标对象的实际方法
Object result = method.invoke(target, args);
System.out.println("end");
return result;
}
/**
* 通过Proxy.newProxyInstance 生成代理对象(重要的方法)
*/
public Object getProxy() {
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
target.getClass().getInterfaces(), this); //创建代理类的核心代码
}
public static void main(String[] args) {
// 实例化目标对象
User user = new UserImpl();
// 用目标对象实例化InvocationHandler
InvocationHandlerImpl invocationHandler = new InvocationHandlerImpl(user);
// 生成代理对象
User proxyUser = (User) invocationHandler.getProxy();
// 调用代理对象的方法,实际上就是调用了invocationHandler的invoke方法
proxyUser.sayHello();
}
}
3.底层原理
作用是拦截目标类的方法。
具体的实现是,通过生成接口实现类的代理类来拦截的。
那代理类又是怎么生成的呢?基于jdk的动态代理技术,其实就是反射包里的Proxy类。
4.拦截器的作用
拦截业务类的业务方法,然后
1.前置业务
2.业务类的业务方法
3.后置业务
运行结果
start //拦截器的前置业务
hello //业务类的业务方法
end //拦截器的后置业务
源码分析
生成代理类的核心代码,这是应用层。
源码层
jdk源码注释更详细见参考里的链接。
为什么jdk自带的动态代理必须是接口?
jdk自带的动态代理只支持接口,为什么?
代理类
代理类的类文件是动态生成的(动态生成的意思是运行时生成的),生成的结果就是一个类文件,名字是$Proxy0.class。
类文件里面的核心代码是,调用InvocationHandler实现类(即拦截器)的方法。
参考
jdk8和低版本jdk的实现有点不一样
juejin.cn/post/693008… //jdk8
www.iteye.com/blog/rejoy-… //低版本jdk