IOC与AOP讲解分析

IoC(控制反转)与AOP(面向切面编程)详解及示例

1. IoC(控制反转)​

核心思想:将对象的创建和依赖管理交给容器,而非在代码中硬编码依赖关系,实现解耦。
依赖注入(DI)​是IoC的一种实现方式,常见形式包括:构造器注入、Setter注入、字段注入。


示例:传统代码 vs. Spring IoC

传统代码(紧耦合)​

java

public class UserService {
    // 直接创建依赖对象(紧耦合)
    private UserDao userDao = new UserDaoImpl();

    public void saveUser(User user) {
        userDao.save(user);
    }
}

使用Spring IoC(解耦)​

  1. 定义接口和实现类

java

public interface UserDao {
    void save(User user);
}

@Component // 声明为Spring管理的Bean
public class UserDaoImpl implements UserDao {
    public void save(User user) {
        System.out.println("保存用户: " + user);
    }
}

@Service // 声明Service层Bean
public class UserService {
    @Autowired // 自动注入依赖
    private UserDao userDao;

    public void saveUser(User user) {
        userDao.save(user);
    }
}
  1. 配置Spring容器(Java Config)​

java

@Configuration
@ComponentScan("com.example") // 扫描包下的组件
public class AppConfig {
}
  1. 使用容器获取Bean

java

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = context.getBean(UserService.class);
        userService.saveUser(new User("Alice"));
    }
}

关键点

  • @Component@Service等注解将类交给Spring管理。
  • @Autowired自动注入依赖,无需手动创建对象。
  • 容器 (ApplicationContext) 负责Bean的生命周期和依赖关系。

2. AOP(面向切面编程)​

核心思想:将横切关注点(如日志、事务)从业务逻辑中分离,通过切面(Aspect)统一处理,提升模块化。


AOP核心概念
  • 切面(Aspect)​:封装横切逻辑的模块(如日志切面)。
  • 连接点(Join Point)​:程序执行的点(如方法调用)。
  • 通知(Advice)​:在连接点执行的动作(如@Before@After)。
  • 切点(Pointcut)​:匹配连接点的表达式(如execution(* com.example.service.*.*(..)))。

示例:日志切面
  1. 定义切面类

java

@Aspect // 声明为切面
@Component // 由Spring管理
public class LoggingAspect {

    // 定义切点:匹配service包下所有方法
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceMethods() {}

    // 前置通知:方法执行前记录日志
    @Before("serviceMethods()")
    public void logBefore(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.println("方法调用前: " + methodName);
    }

    // 后置通知:方法执行后记录日志(无论是否异常)
    @After("serviceMethods()")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("方法调用后: " + joinPoint.getSignature().getName());
    }

    // 环绕通知:统计方法执行时间
    @Around("serviceMethods()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed(); // 执行目标方法
        long duration = System.currentTimeMillis() - start;
        System.out.println("方法执行耗时: " + duration + "ms");
        return result;
    }
}
  1. 启用AOP支持

java

@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy // 启用AOP自动代理
public class AppConfig {
}
  1. 业务类

java

@Service
public class OrderService {
    public void createOrder() {
        System.out.println("创建订单...");
    }
}
  1. 测试AOP效果

java

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        OrderService orderService = context.getBean(OrderService.class);
        orderService.createOrder();
    }
}

输出结果

方法调用前: createOrder
创建订单...
方法调用后: createOrder
方法执行耗时: 2ms

总结
  • IoC优势

    • 降低耦合度,提升代码可维护性。
    • 便于单元测试(依赖可Mock注入)。
  • AOP优势

    • 横切关注点集中管理,避免代码重复。
    • 提升系统可扩展性(如动态添加日志、事务)。

应用场景

  • IoC广泛用于管理Bean依赖(如Service依赖DAO)。
  • AOP适用于日志、事务、权限校验、性能监控等场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值