总结摘要
Spring AOP Aspect 扩展知识
Aspect 动态代理方式
在Spring AOP中,如果目标类实现了至少一个接口,Spring默认会使用JDK动态代理。
JDK动态代理只能代理接口中定义的方法。普通类自身定义的方法(未在接口中声明)不会被代理,代理对象无法“看到”这个方法。
为什么默认使用 JDK 动态代理?
- 遵循面向接口编程的原则。
- 性能与兼容性。
- 启动性能:JDK 动态代理在运行时生成代理类的速度通常比 CGLIB 快。
- 无额外依赖:JDK 动态代理是 Java 标准库的一部分,无需引入第三方库(如 CGLIB),减少依赖冲突风险。
如何强制使用 CGLIB?
- 全局配置。
@EnableAspectJAutoProxy(proxyTargetClass = true)
。 - 单点配置。
@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