Spring中使用的动态代理主要有两种实现方式:JDK动态代理和CGLIB(Code Generation Library)动态代理。这两种代理方式有一些区别,适用于不同的情况。

1. JDK动态代理:

  • 基于接口: JDK动态代理是基于接口的代理,被代理的类必须实现至少一个接口。
  • Proxy类: JDK动态代理通过java.lang.reflect.Proxy类实现,使用Java的反射机制生成代理类。
  • 性能: 通常来说,JDK动态代理相对较轻量,生成的代理类直接实现了被代理接口的方法,不涉及字节码的生成和加载,因此在运行时性能较高。
  • 限制: 只能代理实现了接口的类,不能代理没有实现接口的类。

2. CGLIB动态代理:

  • 基于继承: CGLIB动态代理是基于继承的代理,被代理的类无需实现接口。
  • Enhancer类: CGLIB通过net.sf.cglib.proxy.Enhancer类实现,使用字节码生成技术生成一个被代理类的子类。
  • 性能: 由于使用了字节码生成技术,CGLIB动态代理生成的代理类通常比较庞大,生成和加载代理类的性能相对较低。但一旦生成,调用代理方法的性能可以比JDK动态代理高。
  • 无需接口: 可以代理没有实现接口的类。

选择原则:

  • 如果目标对象实现了接口,优先选择JDK动态代理。
  • 如果目标对象没有实现接口,或者需要代理的是类而不是接口,那么只能使用CGLIB动态代理。

在Spring中,默认情况下,如果目标对象实现了至少一个接口,则使用JDK动态代理,否则使用CGLIB动态代理。可以通过配置来强制使用一种代理方式,或者通过使用@Primary注解来指定首选的代理方式。例如:

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 强制使用CGLIB代理
public class AppConfig {
    // 配置内容
}

总体而言,JDK动态代理和CGLIB动态代理各有优劣,选择取决于具体的业务需求和对象结构。

Was this helpful?

0 / 0

发表回复 0

Your email address will not be published.