spring aop默认使用什么代理
-
Spring AOP默认使用的代理是基于Java动态代理的。Java动态代理是由Java标准库提供的一种实现动态代理的方式,通过在运行时创建一个实现一组接口的代理类来实现动态代理。
在Spring AOP中,使用的是 JDK 动态代理。当目标对象实现了至少一个接口时,默认使用 JDK 动态代理来生成代理类。JDK 动态代理是利用 Java 的反射机制实现的,在运行时动态生成代理类,并将代理类中的方法调用转发给目标对象。
Spring AOP是基于代理类进行方法拦截的。在使用 Spring AOP时,通过配置切面和切点,将需要进行拦截的方法与切面绑定,然后在程序运行时,当目标对象的方法被调用时,代理类会先执行代理的逻辑,再调用目标对象的对应方法。
需要注意的是,JDK 动态代理只能针对接口进行代理,如果目标对象没有实现任何接口,就无法使用 JDK 动态代理。对于没有实现接口的类,Spring AOP会使用 CGLIB(Code Generation Library)动态代理来生成代理类。CGLIB 是一个开源的代码生成类库,它通过生成子类的方式实现动态代理。
总结起来,Spring AOP默认使用的代理是基于Java动态代理,当目标对象实现了接口时,使用JDK动态代理;当目标对象没有实现接口时,使用CGLIB动态代理。
1年前 -
Spring AOP默认使用的是动态代理。Spring AOP支持两种类型的代理:基于接口的代理(JDK动态代理)和基于类的代理(CGLIB代理)。在使用Spring AOP时,如果目标对象实现了至少一个接口,则会使用JDK动态代理,否则使用CGLIB代理。
-
JDK动态代理:JDK动态代理是通过Java反射机制实现的。当使用JDK动态代理时,Spring AOP会生成一个实现目标对象接口的代理类,并在运行时将方法调用转发给该代理类的处理器。JDK动态代理的一个限制是只能代理实现了接口的目标对象。
-
CGLIB代理:CGLIB代理是通过继承目标对象类并重写其中的方法实现的。当使用CGLIB代理时,Spring AOP会生成一个继承目标对象类的代理类,并在运行时将方法调用转发给该代理类的处理器。CGLIB代理可以代理没有接口的目标对象,但代理的过程需要消耗更多的资源。
-
选择代理类型:Spring AOP会自动选择代理类型。如果目标对象实现了至少一个接口,则会使用JDK动态代理;否则使用CGLIB代理。可以通过配置来强制使用某种代理类型,如通过使用<aop:aspectj-autoproxy proxy-target-class="true"/>来强制使用CGLIB代理。
-
代理的性能:JDK动态代理相对于CGLIB代理来说,由于使用了Java反射机制,性能上略逊一筹。因此,在性能要求较高的情况下,可以选择配置使用CGLIB代理。但需要注意的是,CGLIB代理需要类的字节码文件,因此对于动态生成的类或未定义完全的类,无法使用CGLIB代理。
-
代理对象的实例化:无论使用JDK动态代理还是CGLIB代理,被代理的对象都需要在Spring容器中进行配置。Spring AOP仅对Spring容器中的bean进行代理。如果使用AspectJ注解来声明切面,则必须实例化切面类,并将其作为Spring容器中的bean才能被代理。
1年前 -
-
在Spring AOP中,默认使用的是基于Java动态代理的代理实现。
Java动态代理是一种利用反射机制在运行时动态创建代理类和代理对象的技术。在Spring AOP中,如果被代理的目标对象实现了至少一个接口,那么Spring AOP会使用JDK动态代理来创建代理对象。JDK动态代理是通过在运行时创建一个实现了目标接口的代理类来实现的,代理类会实现目标接口中的方法,并在方法调用前后进行拦截、增强等操作。
下面是Spring AOP使用基于JDK动态代理的示意图:
+-------------------------+ | 目标对象 | +-------------------------+ / | \ / | \ +-----------------------+--------------------------+ | 代理对象 | | (实现至少一个接口) | +-----------------------+ /\ || JDK动态代理 || \/ +-------------------------+ | 拦截器链 | +-------------------------+如果被代理的目标对象没有实现任何接口,Spring AOP会使用CGLIB来创建代理对象。CGLIB是一个强大的第三方库,能够在运行时动态生成被代理类的子类,子类重写了父类中的方法,并添加了增强代码。
下面是Spring AOP使用CGLIB进行代理的示意图:
+-------------------------+ | 目标对象 | +-------------------------+ / | \ / | \ +---------------------------+-----------------------------+ | 代理对象 | | (继承自目标对象) | +---------------------------+ /\ || CGLIB代理 || \/ +----------------+ | 拦截器链 | +----------------+需要注意的是,如果目标对象实现了接口,则无论是否明确声明使用JDK动态代理还是CGLIB代理,Spring AOP都会使用JDK动态代理。只有当目标对象没有实现接口时,Spring AOP才会使用CGLIB代理。
在Spring中,可以通过配置来声明具体使用哪种代理方式。可以使用
<aop:aspectj-autoproxy proxy-target-class="true"/>来强制使用CGLIB代理,即使目标对象实现了接口。1年前