关于spring IOC的学习笔记整理

控制反转和依赖注入

ioc的核心是DI,目的就是提供一种更简单的机制来设置组件依赖项,并在整个生命周期中管理这些依赖项。需要某些依赖项的组件通常被称为依赖对象,或者在ioc的情况下被称为目标对象。通常ioc可以分解为两种子类型:依赖注入和依赖查找,这些子类型被进一步分解为ioc服务的具体实现。通过这个定义可以清楚的看到,当谈论DI时,通常是在谈论ioc,而当谈论ioc时,并不总是在谈论DI(依赖查找也是ioc的一种形式)。使用依赖查找时,组建必须对依赖项的引用,而使用依赖注入时,依赖项将通过ioc容器注入组件,依赖查找有两种类型:依赖拉取,上下文依赖查找。依赖注入有两种类型:构造函数注入和setter注入。下面一一介绍

依赖拉取

依赖拉取是最常见的ioc类型,在依赖拉取中,根据需要从注册表中提取依赖项。

未命名文件 (1).png

Spring还提供依赖拉取作为一种检索框架所管理组件的机制:

public class DependencyPull {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/app-context.xml");
        MessageRenderer mr = applicationContext.getBean("renderer",MessageRenderer.class);
        mr.render();
    }
}

上下文依赖查找

上下文依赖朝朝在某些方面与依赖拉取类似,查找是针对管理资源的容器执行的,而不是来自某个中央注册表,并且通常在某个设定点执行。

未命名文件 (2).png

依赖查找通过组件实现以下接口来进行工作,通过实现这个接口,一个组件可以向容器发送它想要获取依赖项的信号。

public interface ManagedComponent {
    void performLookup(Container container);
}
public interface Container {
    Object getDependency(String key);
}
public class ContextualizedDependencyLookup implements ManagedComponent {
    private Depency depency;
    public void performLookup(Container container) {
        this.depency =(Depency) container.getDependency("myDependency");
    }

    @Override
    public String toString() {
        return depency.toString();
    }
}

当容器准备将依赖项传递给组件时,会依次调用每个组件的performLookup() 方法,然后组件可以使用container接口查找所需的依赖项。

构造函数注入

当在组件的构造函数中提供依赖项时,就会发生构造函数依赖注入。首先生命一个或一组构造函数,并将其依赖项作为参数,然后在组件实例化时由ioc容器将依赖项传递给组件。使用构造函数注入的一个显而易见的结果是,如果没有依赖项就不能创建对象,因此必须有依赖项。

public class ConstructorInjection {
    private Dependency dependency;

    public ConstructorInjection(Dependency dependency) {
        this.dependency = dependency;
    }

    @Override
    public String toString() {
        return dependency.toString();
    }
}

setter注入

在setter注入中,ioc容器可以通过setter方法注入组件的依赖项。组件的setter方法公开了ioc容器可以管理的依赖项。使用setter注入的一个显而易见的后果是,可以在没有依赖项的情况下创建对象,然后可以通过调用setter来提供依赖项。实际上,setter注入是使用最广泛的注入机制,也是最简单的ioc机制之一。

public class SetterInjection {
    private Dependency dependency;

    public void SetterInjection(Dependency dependency) {
        this.dependency = dependency;
    }

    @Override
    public String toString() {
        return dependency.toString();
    }
}

注入与查找

现在问题来了,如果可以选择,应该使用哪种方法,注入还是查找?答案绝对是注入。一方面,注入对组件没有任何影响。另一方面,依赖拉取必须主动获得对注册表的引用并与其交互以获取依赖项。

如果使用注入,则可以自由的使用与ioc容器完全分离的类,而ioc容器通过手动为他们的协作者提供依赖对象;而如果使用查找,那么你的类总是依赖于容器定义的类和接口。查找的另一个缺点是难以独立于容器来测试类,而使用注入则可以非常容易的测试自己的组件,因为可以通过使用适当的构造函数或setter来提供依赖项。

setter注入和构造函数注入

现在问题又来了,我们已经选择使用注入了,但是是选择setter注入还是构造函数注入?答案是灵活使用

当在使用组件之前必须拥有一个依赖类的实例时,构造函数注入就特别有用了,但如果使用构造函数注入,则可以通过一种容器无关的方式声明对依赖项的需求,此外,构造函数注入也有助于实现不可变对象的使用。

setter注入在各种情况下都很有用。如果组件向容器公开了它的依赖项,并乐于提供自己的默认值,那么setter注入通常是实现此目的的最佳方法。setter注入的另一个好处是,它允许在接口上声明依赖项,尽管这种方法并没有前面的方法有用。setter注入还允许即时交换针对不同实现的依赖项,而无须创建父组件的新实例。Spring的JMX支持使这项功能成为可能。也许setter注入的最大好处是,它是注入机制中侵入性最小的。

一般来说,应根据使用情况选择注入类型。基于setter的注入允许在不创建新对象的情况下交换依赖项,并且还可以让类选择适当的默认值,而无须显式注入对象。当想要确保将依赖项传递给组件和设计不可变对象时,构造函数注入是一个不错的选择。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容