全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 8 分钟 ✍️ juanwangdev

AOP代理

Spring AOP通过动态代理机制实现切面织入,代理对象在调用目标方法前后执行通知逻辑。

两种代理方式

JDK动态代理

基于接口的代理,要求目标类实现至少一个接口。

Java
// 目标类必须实现接口
public interface UserService {
    void save();
}

public class UserServiceImpl implements UserService {
    public void save() {
        System.out.println("保存用户");
    }
}

CGLIB代理

基于继承的代理,通过生成目标类的子类实现代理。

Java
// 目标类无需实现接口
@Service
public class UserService {
    public void save() {
        System.out.println("保存用户");
    }
}

代理选择规则

条件代理方式
目标类实现接口JDK动态代理(默认)
目标类无接口CGLIB代理
强制使用CGLIB设置 proxyTargetClass=true

配置方式

强制使用CGLIB

Java
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
}
properties
# application.properties
spring.aop.proxy-target-class=true

代理对象创建过程

Java
// 1. Spring容器启动时检测切面
// 2. 发现目标Bean匹配切入点
// 3. 创建代理对象替代目标Bean
// 4. 注入到其他Bean的是代理对象

@Service
public class OrderService {
    @Autowired
    private UserService userService; // 注入的是代理对象
}

代理调用流程

Java
客户端调用 → 代理对象 → 前置通知 → 目标方法 → 后置通知 → 返回结果
text
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
    // 1. 前置逻辑
    System.out.println("方法开始");

    // 2. 调用目标方法
    Object result = joinPoint.proceed();

    // 3. 后置逻辑
    System.out.println("方法结束");

    return result;
}

两种代理对比

特性JDK动态代理CGLIB代理
实现方式接口实现继承子类
性能生成快,调用慢生成慢,调用快
限制必须有接口不能代理final类/方法
Spring默认有接口时使用无接口时使用

Spring 5.x后CGLIB性能优化,两种代理性能差异可忽略。

要点总结

  1. Spring AOP使用JDK动态代理和CGLIB两种代理方式
  2. 有接口默认用JDK代理,无接口用CGLIB代理
  3. 可通过proxyTargetClass=true强制使用CGLIB
  4. 代理对象在容器启动时创建,替代目标Bean注入
  5. CGLIB不能代理final类和final方法

📝 发现内容有误?点击此处直接编辑

← 上一篇 自动装配
下一篇 → AOP切入点表达式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库