为什么 Spring 不建议自己 new 对象?一文彻底搞懂 IOC 本质
很多刚学 Spring 的人,都会有一个疑问:
OrderService orderService = new OrderService();
这样写有什么问题?
对象不是创建出来了吗?
代码不是也能跑吗?
为什么 Spring 一定要:
@Autowired
private OrderService orderService;
很多文章会告诉你:
“这是为了降低耦合”
但其实:这个解释太浅了
因为:即使你自己 new, 照样也可以通过接口解耦
真正的问题,从来不是:
“能不能 new”
而是:
“谁来管理对象”
一、自己 new 最大的问题是什么?
先看一个最简单的例子:
public class OrderService {
public void createOrder() {
System.out.println("创建订单");
}
}
使用:
OrderService orderService = new OrderService();
orderService.createOrder();
完全没问题,于是很多人会觉得:
Spring 好像只是帮我少写了一个 new
其实不是。因为:
一旦对象由你自己 new
Spring 就彻底失去了对它的控制
而这,才是问题的核心
二、Spring 真正想控制的是什么?
很多人理解 IOC:
控制反转 = 对象交给 Spring 创建
这只是表面
真正核心其实是:
“对象控制权”
更准确地说:
Spring IoC 容器
接管的是:
- 对象创建
- 对象装配
- 生命周期管理
的控制权
包括:
- 对象什么时候创建
- 对象什么时候销毁
- 对象依赖谁
- 对象是否单例
- 对象是否需要代理
- 对象是否需要事务增强
- 对象是否需要缓存增强
这些,都需要 Spring 接管
三、IOC 为什么叫“控制反转”?
这里有一个非常经典的设计思想:
好莱坞原则(Hollywood Principle)
Don’t call us, we’ll call you.
别找我们,我们找你(不要主动调用我们,我们会在合适的时候调用你)
什么意思?
传统开发:
new OrderService().createOrder();
是:
你主动控制对象
你决定:
- 什么时候创建
- 什么时候调用
- 怎么依赖
而 Spring 的模式是:
框架接管对象
再在合适的时候主动调用你
例如:
- HTTP 请求来了,Spring 调 Controller
- 定时任务时间到了,Spring 调方法
- Bean 初始化完成,Spring 调生命周期回调
- 事务开启后,Spring 再调业务方法
这才是真正的:
“控制反转”
反转的,不是对象
而是:
“对象与调用流程的控制权”
四、为什么 Spring 一定要接管对象?
因为:
Spring 的很多能力
本质上都建立在:
## “对象可控”
这个前提上
比如:
1、事务
例如:
@Transactional
public void createOrder() {
}
很多人以为:
@Transactional 是 Java 语法能力
其实不是。
本质上:
Spring 在运行时,
偷偷给你创建了一个“代理对象”
真正执行的,
并不是你写的那个对象
而是:
代理对象
-> 拦截方法
-> 开启事务
-> 调用原方法
-> 提交事务
问题来了
如果对象是你自己 new 的:
OrderService service = new OrderService();
Spring 根本不知道这个对象存在
那它还怎么增强?事务自然失效
2、AOP
比如日志:
@Before
public void log() {
}
或者权限:
@PreAuthorize
这些能力,本质上也都依赖:
Spring 先接管对象
再生成代理对象。
如果你自己 new:
Spring 根本插不进来
3、依赖注入
例如:
@Service
public class OrderService {
@Autowired
private UserService userService;
}
为什么 userService 能自动注入?
因为:
Spring 在创建 OrderService 时
会主动帮你把依赖塞进去
如果你自己:
new OrderService();
那 Spring 根本没参与创建过程,自然不会注入
于是:
userService == null
五、很多人其实一直误解了 IOC
很多教程:一上来就说:
IOC 是为了解耦
这句话不能说错,但:
解耦只是结果
不是本质,真正本质其实是:
“框架接管对象生命周期”
只有这样:
Spring 才能:
- 做事务
- 做 AOP
- 做缓存
- 做权限
- 做自动注入
- 做扩展增强
六、为什么说 Spring 本质是一个“对象管理框架”?
很多人觉得:
Spring = Bean 工厂
其实这也太浅了,Spring 真正强大的地方是:
它不仅创建对象
更重要的是:
它管理对象的整个生命周期
包括:
- 创建
- 初始化
- 注入依赖
- 增强代理
- 销毁
这也是为什么:
Spring 几乎所有核心能力, 最后都会回到:
Bean 生命周期
七、为什么大型框架都喜欢“接管对象”?
不仅 Spring,
你会发现:
- Spring
- Dubbo
- MyBatis
- Netty
- Tomcat
这些框架都有一个共同点:
“框架控制对象”
为什么?
因为:
只有控制对象
框架才能控制行为
否则:
开发者随便 new
框架根本无法:
- 插件化
- 统一增强
- 生命周期管理
- 上下文管理
八、那是不是所有对象都不能自己 new?
当然不是,很多初学者容易走向另一个极端:
“是不是所有对象都必须交给 Spring?”
其实并不是
例如:
new User()
new ArrayList<>()
new HashMap<>()
这种普通数据对象, 完全可以自己创建
因为它们:
- 不需要事务
- 不需要 AOP
- 不需要生命周期管理
- 不需要依赖注入
Spring 真正需要接管的
通常是:
“承载业务逻辑的组件对象”
比如:
- Service
- Controller
- Repository
- Component
因为这些对象:
需要被框架增强和管理
所以:判断一个对象是否应该交给 Spring,核心不是:
“能不能 new”
而是:
“它是否需要被框架管理”
九、真正理解 IOC 后,你会发现:
Spring 最核心的思想,其实不是:
“帮你创建对象”
而是:
“拿走对象控制权”
Spring 从来不只是一个:
“对象工厂”
它真正厉害的地方是:
让整个应用中的对象
第一次变得“可管理”,这才是真正的:
Inversion Of Control(控制反转)
关于老潘:
持续拆 Spring、MySQL、Redis 底层原理,复盘真实线上问题。
一起把“会用”变成“看懂”。
如果有帮助,点个赞、收藏支持一下。
下一篇:IOC 真正反转的到底是什么?很多人第一步就理解错了
感兴趣可以关注,避免刷着刷着找不到。
更多推荐



所有评论(0)