Spring已经占据咱们Java开发框架中的半壁江山了,从一开始工做咱们就在使用Spring。可是到底为何要用Spring,可能不少人都没有去思考过这个问题?许多人可能也疲于应对需求,无暇思考这种看似理所固然的问题。那今天,咱们就好好来讨论一下究竟为何要使用Spring IOC?html
假设在最初没有Spring IOC这种框架的时候,咱们采用传统MVC的方式来开发一段常见的用户逻辑。mysql
用户DAO程序员
public class UserDAO { private String database; public UserDAO(String dataBase) { this.database = dataBase; } public void doSomething() { System.out.println("保存用户!"); } }
用户Servicespring
public class UserService { private UserDAO dao; public UserService(UserDAO dao) { this.dao = dao; } public void doSomething() { dao.doSomething(); } }
用户Controllersql
public class Controller { public UserService service; public Controller(UserService userService) { this.service = userService; } public void doSomething() { service.doSomething(); } }
接下来咱们就必须手动一个一个建立对象,并将dao、service、controller依次组装起来,而后才能调用。数据库
public static void main(String[] args) { UserDAO dao = new UserDAO("mysql"); UserService service = new UserService(dao); Controller controller = new Controller(service); controller.doSomething(); }
分析一下这种作法的弊端有哪些呢?编程
这时候咱们再来看看若是用SpringIOC的状况,刚才的代码变成以下。app
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml"); Controller controller = (Controller) context.getBean("controller"); controller.doSomething(); }
很明显,使用IOC以后,咱们只管向容器索取所需的Bean便可。IOC便解决了如下的痛点:框架
经过这个例子可能读者有点如有所思了,那咱们再来看一下IOC的定义是什么。组件化
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,能够用来减低计算机代码之间的耦合度。其中最多见的方式叫作依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。经过控制反转,对象在被建立的时候,由一个调控系统内全部对象的外界实体将其所依赖的对象的引用传递给它。也能够说,依赖被注入到对象中。
控制反转,控制体如今什么地方?控制就体如今咱们一开始的例子,上层须要去控制new下层对象。而反转意味着什么呢?
反转意味着咱们把对象建立的控制权交出去,交给谁呢?交给IOC容器,由IOC容器负责建立特定对象,并填充到各个声明须要特定对象的地方。同窗们可能会对IOC和DI以为很绕,其实IOC至关于接口,它规定了要实现什么?而依赖注入(DI)就是具体的实现,它实现了IOC想要的效果。IOC的思想很好地体现了面向对象设计法则之一——好莱坞法则:“别找咱们,咱们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
如何减低耦合?咱们举个例子,当在IDEA开发环境中咱们添加插件的时候,却须要去知道该插件须要什么依赖,要怎么才能成功开启插件?是否是对用户至关不友好呢?既然咱们要使用插件,意味着咱们和插件之间是耦合的,没法避免。可是若是咱们还须要知道插件须要的依赖和开启插件的步骤,说明咱们和插件之间的耦合关系更强烈了。因此SpringIOC的定义当中写道“下降耦合”而非“消除耦合”,但只要耦合度下降的话,就有利于代码的维护和扩展。思考一下?是否是跟Maven的机制很相似呢?在Maven中声明依赖的话,Maven的自动将该依赖所需的其余依赖递归的寻找。你能够把你本身想象成一个对象的设计师,你设计了一张对象内部构造的图纸,交给SpringIOC,它会自动地根据这份图纸生成这个对象。
IOC容器实现了开发中对象粒度的一种组件化,将每一个对象当作组件同样放进容器当中。而每一个组件都是可插拔,这种是最佳的对象解耦方式。一方面经过将对象之间的耦合关系从编译期推迟到运行期。一旦有须要这个对象的话,就直接使用,客户程序员彻底不须要知道这个对象的前因后果。而且IOC容器对Bean的统一管理使得AOP的实现更加的方便。这样一来,咱们客户程序员就能够更专一在业务代码的编写上。