Spring使用-Aspect-扩展知识

总结摘要
Spring AOP Aspect 扩展知识

Aspect 动态代理方式

在Spring AOP中,如果目标类实现了至少一个接口,Spring默认会使用JDK动态代理。

JDK动态代理只能代理接口中定义的方法。普通类自身定义的方法(未在接口中声明)不会被代理,代理对象无法“看到”这个方法。

为什么默认使用 JDK 动态代理?

  1. 遵循面向接口编程的原则。
  2. 性能与兼容性。
    1. 启动性能:JDK 动态代理在运行时生成代理类的速度通常比 CGLIB 快。
    2. 无额外依赖:JDK 动态代理是 Java 标准库的一部分,无需引入第三方库(如 CGLIB),减少依赖冲突风险。

如何强制使用 CGLIB?

  1. 全局配置。@EnableAspectJAutoProxy(proxyTargetClass = true)
  2. 单点配置。@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)修饰单个 bean。

验证 JDK 动态代理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Component
public class AspectOperationJdkProxyImpl implements AspectOperationJdkProxy {
    @Override
    public void serviceInterface() {
        System.out.println("[SpringAOP][ProxyType] serviceInterface from " + this.getClass().getName());
    }

    public void serviceMethod() {
        System.out.println("[SpringAOP][ProxyType] serviceMethod from " + this.getClass().getName());
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 验证 JDK 动态代理
// 打印内容如下:
// [SpringAOP][ProxyType] serviceInterface from tech.gdev.springbasicexplore.aop.springaop.AspectOperationJdbProxyImpl
// [SpringAOP][ProxyType] not a AspectOperationJdbProxyImpl
AspectOperationJdkProxy aspectOperationJdkProxy = applicationContext.getBean(AspectOperationJdkProxy.class);
aspectOperationJdkProxy.serviceInterface();
if (aspectOperationJdkProxy instanceof AspectOperationJdkProxyImpl) {
    ((AspectOperationJdkProxyImpl) aspectOperationJdkProxy).serviceMethod();
} else {
    System.out.println("[SpringAOP][ProxyType] not a AspectOperationJdbProxyImpl");
}

验证 CGLIB 动态代理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Component
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
public class AspectOperationCglibProxyImpl implements AspectOperationCglibProxy {
    @Override
    public void serviceInterface() {
        System.out.println("[SpringAOP][ProxyType] serviceInterface from " + this.getClass().getName());
    }

    public void serviceMethod() {
        System.out.println("[SpringAOP][ProxyType] serviceMethod from " + this.getClass().getName());
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 验证 CGLIB 动态代理
// 打印内容如下:
// [SpringAOP][ProxyType] serviceInterface from tech.gdev.springbasicexplore.aop.springaop.AspectOperationCglibProxyImpl
// [SpringAOP][ProxyType] serviceMethod from tech.gdev.springbasicexplore.aop.springaop.AspectOperationCglibProxyImpl
AspectOperationCglibProxy aspectOperationCglibProxy = applicationContext.getBean(AspectOperationCglibProxy.class);
aspectOperationCglibProxy.serviceInterface();
if (aspectOperationCglibProxy instanceof AspectOperationCglibProxyImpl) {
    ((AspectOperationCglibProxyImpl) aspectOperationCglibProxy).serviceMethod();
} else {
    System.out.println("[SpringAOP][ProxyType] not a AspectOperationCglibProxyImpl");
}

END