IOC是啥?外卖小哥帮你送饭
IOC(控制反转)就像一个“外卖小哥”,原本你需要你自己买菜、做饭(手动创建和管理对象),现在你只需要下单(定义需求),外卖小哥(IOC容器)就会把做好的饭菜(对象)送到你家(程序里)
核心特点:
控制权反转:原本你控制对象的创建和依赖,现在交给“外卖小哥”管理。
解耦:对象之间不再直接“绑定”,就像你不用关心外卖小哥怎么买菜做饭,只管吃就行。
IOC有啥用?
1. 省事省力:
不用手动造对象:比如一个“订单服务”需要依赖“支付工具”,传统写法要自己new 支付工具(),现在交给IOC容器自动注入。
减少重复代码:比如每个类都要写日志,IOC可以通过切面(AOP)统一处理,不用每个方法都写一遍 。
2. 灵活替换:
今天用支付宝支付,明天换微信支付?改配置就行,不用改代码 。
适合多人协作:张三负责写支付工具,李四只管调用,互不干扰。
3. 方便测试:
测试时可以用“假数据”(Mock对象)代替真实数据库,IOC容器自动注入,不用改业务代码 。
IOC怎么用?
核心步骤:定义对象 → 交给容器管理 → 自动注入
1.定义对象(点菜)
传统方式:手动 new 对象(),比如:
UserService userService = new UserService();
IOC方式:用注解或配置文件告诉容器“这个类归你管”,比如:
@Service // 告诉IOC:“这个类是我的订单服务!”
public class UserService {
// ...
}
2.依赖注入(送餐)
构造函数注入:通过构造函数传递依赖对象(像外卖小哥直接送到门口):
public class UserService {
private PaymentTool paymentTool;
// 构造函数告诉IOC:“我需要一个支付工具!”
public UserService(PaymentTool paymentTool) {
this.paymentTool = paymentTool;
}
}
Setter方法注入:通过Setter方法赋值(像外卖小哥把餐放在门口):
public class UserService {
private PaymentTool paymentTool;
// Setter方法告诉IOC:“把支付工具放这里!”
public void setPaymentTool(PaymentTool paymentTool) {
this.paymentTool = paymentTool;
}
}
3.配置文件或注解(下单菜单)
XML配置(老式菜单):
<bean id="paymentTool" class="com.example.WeChatPayment"/>
<bean id="userService" class="com.example.UserService">
<property name="paymentTool" ref="paymentTool"/>
</bean>
注解配置(扫码点餐):
@Service
public class UserService {
@Autowired // 告诉IOC:“自动把支付工具送过来!”
private PaymentTool paymentTool;
}
四、IOC的实际应用场景
- 电商系统:
订单模块依赖支付、库存、物流模块,IOC容器自动组装。
切换支付方式(支付宝→微信)只需改配置,不影响订单逻辑。 - 微服务架构:
每个服务独立开发,通过IOC容器统一管理依赖,像连锁餐厅分店共用中央厨房。 - 企业管理系统:
权限验证、日志记录等通用功能通过切面(AOP)统一处理,不用每个类都写一遍。
优点 | 缺点 |
---|---|
代码更简洁(少写new) | 学习成本高(要理解容器原理) |
系统更灵活(易替换依赖) | 过度使用可能导致配置复杂 |
适合大型项目(团队协作) | 调试困难(依赖关系不直观) |