一.依赖简介

一个典型的企业应用程序不是由一个单一的对象组成(或Spring的说法中的bean)。即使是最简单的应用程序也只有几个对象一起工作来呈现最终用户看作是一个连贯的应用程序。如何从定义许多独立的bean定义到完全实现的应用程序,在这些应用程序中对象协作实现目标。
 有关spring的设计模式和应用详情可以参考我这篇文章《spring常用设计模式及应用》

二.依赖注入

依赖注入(DI)是一个过程,通过这个过程,对象可以通过构造函数参数,工厂方法的参数或者在构造或返回对象实例后设置的属性来定义它们的依赖关系从工厂方法。然后容器在创建bean时注入这些依赖关系。这个过程从根本上说是相反的,因此名为控制反转(IoC),它本身通过使用类的直接构造或服务定位符模式来控制它自己的依赖关系的实例化或位置。
代码与DI原则相比更加清晰,当对象提供依赖时,解耦更为有效。该对象不查找它的依赖关系,不知道依赖关系的位置或类。因此,您的类变得更容易测试,特别是当依赖关系在接口或抽象基类上时,它们允许在单元测试中使用存根或模拟实现。
DI存在两种主要的变体,基于构造函数的依赖注入和基于Setter的依赖注入

三.基于构造函数的依赖注入

基于构造器的 DI通过容器调用具有多个参数的构造器来完成,每个参数表示一个依赖关系。调用static具有特定参数的工厂方法来构造这个bean几乎是等价的,而且这个讨论同样将参数作为构造函数和static工厂方法来处理。以下示例显示了只能通过构造函数注入进行依赖注入的类。请注意,这个类没有什么特别之处,它是一个POJO,它不依赖于容器特定的接口,基类或注释。

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
}
}

1.构造器参数匹配

构造函数参数解析匹配使用参数的类型进行。如果bean定义的构造函数参数中没有潜在的歧义,那么bean定义中定义构造函数参数的顺序就是在实例化bean时将这些参数提供给适当构造函数的顺序。

package x.y;

public class Foo {

    public Foo(Bar bar, Baz baz) {
        // ...
    }
}

没有潜在的歧义存在,假设Bar和Baz不是继承关系。因此,以下配置好,你不需要指定构造器参数指标明确在<constructor-arg>  索引,类型或类型。

<beans>
    <bean id="foo" class="x.y.Foo">
        <constructor-arg ref="bar"/>
        <constructor-arg ref="baz"/>
    </bean>

    <bean id="bar" class="x.y.Bar"/>

    <bean id="baz" class="x.y.Baz"/>
</beans>

在前面的场景中,如果使用类型属性显式地指定构造函数参数的类型,容器可以使用与简单类型的类型匹配。

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>

使用索引属性指定显式构造函数参数的指数。

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>

同样也可以使用构造器参数名称匹配

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

2.基于Setter方法

在调用无参数构造函数或无参数静态工厂方法实例化bean时,基于bean的调用Setter方法是通过bean调用Setter方法完成的。

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}

Spring团队通常提倡构造函数注入,因为它使一个能够将应用程序组件作为不可变对象实现,并确保所需的依赖项不是null。此外,构造函数注入的组件总是返回到完全初始化状态的客户机(调用)代码中。作为一个方面说明,大量的构造函数的参数是一个糟糕的代码的气味,这意味着类可能有太多的责任和应该被更好的问题解决的适当分离。
 
Setter注入应该主要用于可选的依赖关系,这些依赖关系可以在类中分配合理的默认值。否则,非空检查必须在代码使用依赖项的任何地方执行。第=一个优势就是在于setter方法使该类的对象能够重新配置或重新注入。因此通过JMX MBean管理是setter注入一个引人注目的用例.

Spring依赖注入(DI)详解的更多相关文章

  1. Spring 依赖注入方式详解

    平常的Java开发中,程序员在某个类中需要依赖其它类的方法. 通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想,即依赖类不由 ...

  2. Spring 依赖注入方式详解(四)

    IoC 简介 平常的Java开发中,程序员在某个类中需要依赖其它类的方法. 通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想 ...

  3. Unity依赖注入使用详解

    写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...

  4. SpringDI四种依赖注入方式详解

    文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star!搜索关注微信公众号 [码出Offer] 领取各种学习资料! LOGO SpringDI(依赖注入) 一.DI概述 De ...

  5. Spring IOC 注入方式详解 附代码

    引言 Spring框架作为优秀的开源框架之一,深受各大Java开发者的追捧,相信对于大家来说并不陌生,Spring之所以这么流行,少不了他的两大核心技术IOC和IOP.我们这里重点讲述Spring框架 ...

  6. .NET Core 中依赖注入框架详解 Autofac

    本文将通过演示一个Console应用程序和一个ASP.NET Core Web应用程序来说明依赖注入框架Autofac是如何使用的 Autofac相比.NET Core原生的注入方式提供了强大的功能, ...

  7. AngularJS开发指南10:AngularJS依赖注入的详解

    依赖注入是一种软件设计模式,用来处理代码的依赖关系. 一般来说有三种方法让函数获得它需要的依赖: 它的依赖是能被创建的,一般用new操作符就行. 能够通过全局变量查找依赖. 依赖能在需要时被导入. 前 ...

  8. Spring 依赖注入(DI) 的三种方式 和 对集合类型的注入

    // 分别省略了getter setter public class Student { private String name; private int age; private Teacher t ...

  9. 依赖注入(IOC) 详解

    https://blog.csdn.net/qq_27093465/article/details/52547290 https://blog.csdn.net/qq_27093465/article ...

  10. 1.4 Spring 依赖注入(DI)和控制反转(IOC)详解

    自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html 1.1  Spring 依赖注 ...

随机推荐

  1. Sql 根据当前时间,获取星期一具体日期

    --根据当前时间,计算每周一日期,周日为每周第一天 declare @getDate datetime --set @getDate='2018-12-30' set @getDate='2019-0 ...

  2. css fixed 失效问题解法

    https://stackoverflow.com/questions/11258877/fixed-element-disappears-in-chrome 开启css硬件加速,transform: ...

  3. lodash 判断一个数据是否包含另一个数组

    if (_.intersection(v.ids, value).length == value.length) { this.groupListExtData.push(v.names); }   ...

  4. scrapy 爬取智联招聘

    准备工作 1. scrapy startproject Jobs 2. cd Jobs 3. scrapy genspider ZhaopinSpider www.zhaopin.com 4. scr ...

  5. 通过maven-assembly-plugin将Springboot项目打包成tar.gz压缩包,在Linux环境可执行脚本直接安装成系统服务

    1.在pom.xml中添加maven-assembly-plugin依赖,同时需将默认生成的spring-boot-maven-plugin依赖删除,否则最终打出的发行包启动会有问题 <plug ...

  6. qt quick-初始学习概念

    Qt Quick简介: Qt Quik 是一种高级用户界面技术,使用它可以轻松地创建供移动和嵌入式设备使用到动态触摸式界面和轻量级应用程序:Qt Quick主要由三部份组成: 改进的Qt Creato ...

  7. Go的并发调度原理

    Go语言是为并发而生的语言,Go语言是为数不多的在语言层面实现并发的语言:也正是Go语言的并发特性,吸引了全球无数的开发者.   并发(concurrency)和并行(parallellism) 并发 ...

  8. thymelead入门 git地址在文档最后

    流程:##### 流程###### 1:pom添加依赖 <dependency> <groupId>org.springframework.boot</groupId&g ...

  9. 别人的Linux私房菜(22)软件安装:源代码与Tarball

    执行make,会在当前目录查找makefile文本文件(记录了源代码如何编译的详细信息). 内核相关的函数信息放置在/usr/lib./usr/lib64里. 在Tarball(一般为xxx.tar. ...

  10. python编程之如何在Windows上安装python

    一.安装python 首先检查你的系统里是否安装了python,开始菜单里点击运行输入cmd打开一个命令窗口,或键盘快捷键windows+R打开,在窗口中输入python并回车,如果出现了Python ...