想理解Spring IoC的好处,不妨去读点技术历史 所以说呀程序员也得去读一点「技术历史」才能比较好的去理解新的知识点。像我这种写过「EJB 2.0」的老程序员对Spring里的IoC还是很有实际的感触的。在本文正式开始之前先介绍一下两个蛮实用的学习方法读技术历史了解来龙去脉非常有助于理解后续的新知识点尽量靠近源头去找资料很多你要知道的知识点人家一早就写的很完整很清晰了常有人问Spring IoC有什么好处回答多是解耦、可测试、生命周期等。这些说法都对。但是写过EJB2这种的人是知道整个演变的过程的是更能理解好IOC的。用EJB2.0编程时你会有一种强烈的感觉就是50%的操作不是在写业务代码如下业务代码里要查JNDISessionBean还要走Home、Remote那套接口明明本地调用也得按远程套路写部署描述符和Java代码两套维护改一个DAO有时还得动ejb-jar.xml对象谁创建、谁查找、谁组装真的是满天飞维护代价也跟着水涨船高。当时项目里的局面大概像下面这样。Spring作者Rod Johnson在2002年《Expert One-on-One J2EE Design and Development》第6章里写过类似处境「不用EJB也得有办法管业务对象」否则项目里会混用Singleton、手写Factory配置各写各的很难维护。Spring IoC是在这条背景下萌生的。EJB2里IoC要替代什么EJB容器能管SessionBean、EntityBean那一层但DAO这类细粒度对象容器管得并不好。团队往往在EJB外面再补静态工厂、Singleton各写各的。Spring IoC针对的是这段空白把对象创建和依赖组装「收到一个地方业务类只声明需要什么」。当年最烦的项目里常怎么写Spring IoC改了什么用个Service要先查JNDI要么自己new要么写个getXXX()工厂启动时配好Bean业务代码里直接注入用调Bean要走Home、Remote、create()有的走EJB有的偷偷写成普通Java类两套混着写普通Java类就行谁创建谁交给容器改DAO还得动ejb-jar.xml配置散在XML、properties、甚至数据库里各管各的Bean定义收在一处改依赖改配置少动业务类写单测绕不开容器测试里再抄一遍JNDI或者手工把依赖一个个new进去测试里换一份配置把实现换成Mock就行DAO、工具类EJB管的不好有人用Singleton有人静态工厂各写各的Service、DAO都是Bean同一套容器一起配左半边是EJB2常见写法Client查JNDI拿Home再create SessionBeanBean里可能还要自己管DAO侵入了业务代码。右半边是SpringApplicationContext启动时把Service、DAO装配好业务方法跑起来时依赖已经在那里了。控制反转用大白话说就是谁new、谁组装从业务代码挪到了容器启动阶段。EJB容器里也有inversion of control比如SessionBean的setSessionContext让容器回调你的代码。但关键是不是你有IoC就行了还得从更轻量级、更统一、也更方便单测的维度来考虑Spring做到了。Rod Johnson介绍Spring时还提过Hollywood Principle好莱坞原则大意是别打电话给我我会打给你框架在合适时机调你的代码而不是你的代码到处去调框架。前面两张图、一张表其实都在说同一件事EJB2里装配散在各处。那Spring IoC有什么好处把创建、查找、组装收到容器里业务代码主要写业务。或者我像下面这么描述可能更加容易理解Spring IOC的核心贡献是将‌对象的创建、查找、组装‌这一「控制权」从‌业务代码‌开发者手动new、JNDI lookup、工厂调用‌「反转」‌至‌容器‌ApplicationContext统一管理。原本EJB2.0的设计则是「控制权错位了」。参考的内容《Expert One-on-One J2EE Design and Development》第六章