Spring AOP是什么

让我用一个餐厅服务的例子来解释Spring AOP:

  1. 基本概念展示:
// 核心业务逻辑(相当于餐厅的点菜服务)
public interface OrderService {
    void createOrder(String dish);
}

// 实现类
@Service
public class OrderServiceImpl implements OrderService {
    @Override
    public void createOrder(String dish) {
        System.out.println("制作菜品: " + dish);
    }
}

// 切面(相当于服务流程的统一处理)
@Aspect
@Component
public class ServiceAspect {
    // 定义切点(相当于确定在哪些服务环节进行处理)
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void servicePointcut() {}
    
    // 前置通知(相当于服务前的准备工作)
    @Before("servicePointcut()")
    public void beforeService(JoinPoint joinPoint) {
        System.out.println("服务准备: 清洁餐具");
    }
    
    // 后置通知(相当于服务后的收尾工作)
    @After("servicePointcut()")
    public void afterService() {
        System.out.println("服务结束: 清理餐桌");
    }
    
    // 环绕通知(相当于完整的服务流程控制)
    @Around("servicePointcut()")
    public Object aroundService(ProceedingJoinPoint joinPoint) 
        throws Throwable {
        // 开始计时
        long start = System.currentTimeMillis();
        
        // 执行原有服务
        Object result = joinPoint.proceed();
        
        // 记录服务时间
        long time = System.currentTimeMillis() - start;
        System.out.println("服务用时: " + time + "ms");
        
        return result;
    }
}
  1. 实际应用示例:
// 日志切面
@Aspect
@Component
public class LoggingAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) 
        throws Throwable {
        long start = System.currentTimeMillis();
        
        Object proceed = joinPoint.proceed();
        
        long executionTime = System.currentTimeMillis() - start;
        logger.info(joinPoint.getSignature() + " executed in " + 
            executionTime + "ms");
        
        return proceed;
    }
}

// 自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}

// 使用切面
@Service
public class UserService {
    @LogExecutionTime
    public User findById(Long id) {
        // 业务逻辑
        return userRepository.findById(id);
    }
}
  1. 事务管理示例:
@Aspect
@Component
public class TransactionAspect {
    @Around("@annotation(Transactional)")
    public Object handleTransaction(ProceedingJoinPoint joinPoint) 
        throws Throwable {
        TransactionStatus status = null;
        try {
            // 开启事务
            status = beginTransaction();
            
            // 执行业务逻辑
            Object result = joinPoint.proceed();
            
            // 提交事务
            commitTransaction(status);
            return result;
        } catch (Exception e) {
            // 回滚事务
            if (status != null) {
                rollbackTransaction(status);
            }
            throw e;
        }
    }
}

// 使用事务切面
@Service
public class OrderService {
    @Transactional
    public void createOrder(Order order) {
        // 创建订单的业务逻辑
    }
}
  1. 缓存切面示例:
@Aspect
@Component
public class CacheAspect {
    private Map<String, Object> cache = new ConcurrentHashMap<>();
    
    @Around("@annotation(Cacheable)")
    public Object handleCache(ProceedingJoinPoint joinPoint) 
        throws Throwable {
        // 生成缓存key
        String key = generateKey(joinPoint);
        
        // 检查缓存
        if (cache.containsKey(key)) {
            return cache.get(key);
        }
        
        // 执行方法
        Object result = joinPoint.proceed();
        
        // 存入缓存
        cache.put(key, result);
        return result;
    }
}

// 使用缓存切面
@Service
public class ProductService {
    @Cacheable
    public Product getProductById(Long id) {
        // 获取商品信息的业务逻辑
    }
}
  1. 权限检查切面:
@Aspect
@Component
public class SecurityAspect {
    @Before("@annotation(RequiresPermission)")
    public void checkPermission(JoinPoint joinPoint) {
        // 获取当前用户
        User user = getCurrentUser();
        
        // 获取所需权限
        RequiresPermission annotation = ((MethodSignature) joinPoint
            .getSignature())
            .getMethod()
            .getAnnotation(RequiresPermission.class);
            
        // 检查权限
        if (!hasPermission(user, annotation.value())) {
            throw new AccessDeniedException("权限不足");
        }
    }
}

// 使用权限检查
@Service
public class AdminService {
    @RequiresPermission("ADMIN")
    public void performAdminOperation() {
        // 管理员操作
    }
}

AOP的主要应用场景:

  1. 日志记录
  2. 性能监控
  3. 事务管理
  4. 安全检查
  5. 缓存管理
  6. 错误处理

它就像餐厅服务中的标准流程:

  • 核心业务(点菜、做菜)是主要服务
  • 切面(清洁、记录、计时)是辅助流程
  • 两者结合提供完整的服务体验

AOP的优势:

  1. 代码重用
  2. 关注点分离
  3. 维护性提高
  4. 代码简洁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值