众所周知,使用Spring AOP可以通过生成代理对象增强目标类的方法,那么如果你使用过
Proxy.newProxyInstance()方法生成代理对象你就会发现,代理类必须得实现了接口才能使用此方法
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
也就是说参数要求代理类必须实现了至少一个接口才能使用Proxy.newProxyInstance()方法
而Spring AOP底层也是通过以上方法生成代理对象的
那么使用 Spring AOP 增强的类都要实现接口吗?
答案当然是否定的
事实上Spring AOP既可以基于接口生成代理对象,也可以基于类生成代理对象。在Spring AOP中,如果目标类实现了接口,那么默认情况下会基于接口生成代理对象,这称为基于接口的代理。如果目标类没有实现接口,Spring AOP也支持基于类生成代理对象,这称为基于类的代理。
在基于接口的代理中,Spring会使用JDK动态代理来生成代理对象,而在基于类的代理中,Spring会使用CGLIB来生成代理对象。
也就是说:Spring AOP支持两种主要的代理机制:基于JDK的动态代理和基于CGLIB的字节码操作。
基于JDK的动态代理:
当目标对象至少实现了一个接口时,Spring AOP默认使用JDK的动态代理机制来创建代理对象。这种情况下,确实会使用Proxy.newProxyInstance()方法来生成代理。这个方法接收三个参数:类加载器、目标对象实现的接口数组以及一个实现了InvocationHandler接口的处理器对象。这个处理器对象会在代理对象的方法被调用时负责执行增强逻辑,并调用目标对象的相应方法。
基于CGLIB的字节码操作:
如果目标对象没有实现任何接口,或者配置要求使用CGLIB代理(通过proxy-target-class属性设置为true),那么Spring AOP会使用CGLIB库来创建目标对象的子类作为代理对象。CGLIB通过操作字节码来动态生成子类,并在子类中覆盖目标方法以添加增强逻辑。这种情况下,Proxy.newProxyInstance()方法不会被使用。
本文解释了SpringAOP如何生成代理对象,包括基于接口的JDK动态代理和基于类的CGLIB字节码操作。指出并非所有SpringAOP增强的类都必须实现接口,Spring可以根据配置选择不同的代理机制。
1万+

被折叠的 条评论
为什么被折叠?



