spring的自我理解【IOC、DI】

  • A+
所属分类:java spring

说起spring框架,我认为严格意义上来说spring更像是一个粘合剂【纯属个人观点】。一般都叫spring容器。因为它粘合了别的框架或者组件。所以spring是个容器。程序开发的模块组件都可以通过spring这个容器进行组装拼合,spring为我们提供了很多管理功能。而且,它是一个轻量级的容器。【当spring启动时,创建和销毁的资源都非常少】它的侵入性非常小,也可以说是耦合性很低。可以很轻易的替换掉它,而不需要做太大的改动,它对别的组件的依赖非常小。

spring的自我理解【IOC、DI】

谈到spring必然要想到IOC(Inversion of Control)【控制反转】,它不是一门技术,而是一种设计思想。在java开发中,IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。先要明确谁控制谁,控制什么。
在传统的java SE设计中我们直接在对象内部通过new进行对象的创建,是程序主动去创建依赖对象;而IOC是有一个专门的容器来创建这些对象,即有IOC容器来控制对象的创建;

何为反转?有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

举一个通俗易懂的例子:比如芈月传这个电视剧的剧本,如果编剧在写剧本的时候把芈月直接写为孙俪,直接围绕孙俪这个对象去编剧本,这种方式就相当于传统的java SE的设计思想。而当有了IOC思想之后,编剧写剧本的时候直接写芈月说了什么话,做了什么事直接围绕戏剧人物进行刻画描述,而找演员(创建对象)这种事情交给导演去做。而不是剧本直接定死的,即使孙俪档期冲突了,也可以找王丽,李丽之类的。这就是我对控制反转的个人见解。

说完IOC之后,接下来说一下DI(Dependency Injection)【依赖注入】:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

●谁依赖于谁:当然是应用程序依赖于IoC容器

●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源

●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象

●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

再举一个简单的例子
所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B。
所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果不倒置,意思就是A主动获取B的实例:B b = new B(),这就是最简单的获取B实例的方法(当然还有各种设计模式可以帮助你去获得B的实例,比如工厂、Locator等等),然后你就可以调用b对象了。
所以,不倒置,意味着A要主动获取B,才能使用B;到了这里,你就应该明白了倒置的意思了。倒置就是A要调用B的话,A并不需要主动获取B,而是由其它人自动将B送上门来。

形象的举例就是:

通常情况下,假如你有一天在家里饿了,要吃饭,那么你可以到你小区外面的饭店去,告诉他们,你需要一份黄焖鸡米饭,然后小卖部给你做一份黄焖鸡米饭!

这本来没有太大问题,关键是如果饭店很远,那么你必须知道:从你家如何到饭店;饭店里的黄焖鸡米饭是否已经售罄;你还要考虑是否开着车去;等等等等,也许有太多的问题要考虑了。也就是说,为了吃上一顿黄焖鸡米饭,你还可能需要依赖于车等等这些交通工具或别的工具,问题是不是变得复杂了?那么如何解决这个问题呢?

解决这个问题的方法很简单:饿了么应运而生,凡是饿了么的会员,你只要告知饿了么app你需要什么,骑手将主动把货物给你送上门来!这样一来,你只需要做两件事情,你就可以活得更加轻松自在:
第一:向饿了么注册为会员
第二:在饿了么上面下单

是不是和Spring的做法很类似呢?Spring就是饿了么、饭店,你就是A对象,黄焖鸡米饭就是B对象
第一:在Spring中声明一个类:A
第二:告诉Spring,A需要B

假设A是UserAction类,而B是UserService类

 

在Spring这个饿了么app(工厂)中,有很多对象/服务:userService,documentService,orgService,也有很多会员:userAction等等,声明userAction需要userService即可,Spring将通过你给它提供的通道主动把userService送上门来,因此UserAction的代码示例类似如下所示:

package org.leadfar.web;
public class UserAction{
     private UserService userService;
     public String login(){
          userService.valifyUser(xxx);
     }
     public void setUserService(UserService userService){ 
          this.userService = userService;
     }
}

在这段代码里面,你无需自己创建UserService对象(Spring作为背后无形的手,把UserService对象通过你定义的setUserService()方法把它主动送给了你,这就叫依赖注入!)

所以个人总结下来就是
ioc 相当于 平时我们使用的工厂。
di 相当于 平时我们的setter方法。

有一种落差是,你的才华配不上梦想,你的能力配不上野心,也辜负了所受的苦难。
weinxin
支付宝扫一扫
支付宝领红包

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: