内容来着《收割Offer》

面试官提问

● Spring AOP的实现原理是什么?

● JDK的动态代理的实现原理是什么?

● CGLib实现动态代理的原理是什么?

● 对比JDK动态代理与CGLib的优缺点对比。

Spring的AOP(Aspect Oriented Programming,面向切面编程)是通过动态代理实现的。如果为 Spring 的某个 Bean 配置了切面,那么 Spring 在创建这个 Bean 的时候,实际上创建的是这个 Bean 的一个代理对象,后续对 Bean 中的方法的调用,实际上调用的是代理类重写的代理方法。Spring 的 AOP 使用了两种动态代理,分别是 JDK 的动态代理以及 CGLib 的动态代理。

1)JDK动态代理

类若实现了接口,则 Spring 默认使用 JDK 的动态代理实现 AOP。JDK 动态代理中有两个关键的类或者接口:第一个是 InvocationHandler 接口,使用 JDK 的动态代理需要编写一个类去实现 InvocationHandler 接口,重写 invoke 方法,这个方法就是我们提供的代理方法,前后可以织入逻辑;第二个是 Proxy 类,通过这个类的 newProxyInstance 方法可以返回代理对象。生成的代理类实现了原来那个类的所有接口,并对接口的方法进行了代理,我们通过代理对象调用这些方法时,底层通过反射最终调用我们实现的 invoke 方法。

2)CGLib动态代理

CGLib动态代理底层采用了ASM字节码生成框架,直接对需要代理的类的字节码进行操作,生成这个类的子类,并重写类的所有可重写的方法,在重写的过程中,写入额外的逻辑对方法进行增强。

JDK动态代理与CGLib动态代理的区别总结如下:

(1)JDK动态代理是JDK原生的,它要求类必须实现接口;JDK动态代理通过反射机制生成代理类的速度要比CGLib操作字节码生成代理类的速度更快,但执行代理方法时,反射机制效率比较低,因此,CGLib执行代理方法的效率要高于JDK动态代理。