Spring框架的核心功能之一就是通过依赖注入(dependency injection)的方式来管理Bean之间的依赖关系
每个基于应用程序的 java 都有几个对象,这些对象一起工作来呈现出终端用户所看到的工作的应用程序。当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能独立于其他 Java 类来增加这些类重用的可能性,并且在做单元测试时,测试独立于其他类的独立性。依赖注入(或有时称为布线)有助于把这些类粘合在一起,同时保持他们独立。
不使用依赖注入的代码:
使用依赖注入的代码:
在这里,HelloWorld不应该担心 HelloChina的实现。HelloChina将会独立实现,并且在 HelloWorld实例化的时候将提供给 HelloWorld,整个过程是由 Spring 框架的控制。
在这里,我们已经从 HelloWorld中删除了全面控制,并且把它保存到其他地方(即 XML 配置文件),且依赖关系(即 HelloChina类)通过类构造函数被注入到 TextEditor 类中。因此,控制流通过依赖注入(DI)已经“反转”,因为你已经有效地委托依赖关系到一些外部系统。
依赖注入的第二种方法是通过 TextEditor 类的 Setter 方法
1.Constructor-based dependency injection 当容器调用带有多个参数的构造函数类时,实现基于构造函数的 DI,每个代表在其他类中的一个依赖关系。
当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。
如果构造函数有多个,
可以通过按照参数的顺序在配置Bean来指定值
或者指定类型来传值(可以不用考虑配置的顺序)
或者指定index来传值,从0开始:
或者通过name属性:
如果你想要向一个对象传递一个引用,你需要使用 标签的 ref 属性,如果你想要直接传递值,那么你应该使用如上所示的 value 属性。
2.Setter-based dependency injection 基于 setter 方法的 DI 是通过在调用无参数的构造函数或无参数的静态工厂方法实例化 bean 之后容器调用 beans 的 setter 方法来实现的。
当容器调用一个无参的构造函数或一个无参的静态 factory 方法来初始化你的 bean 后,通过容器在你的 bean 上调用设值函数,基于设值函数的 DI 就完成了
你应该注意定义在基于构造函数注入和基于设值函数注入中的 Beans.xml 文件的区别。唯一的区别就是在基于构造函数注入中,我们使用的是〈bean〉标签中的〈constructor-arg〉元素,而在基于设值函数的注入中,我们使用的是〈bean〉标签中的〈property〉元素。
第二个你需要注意的点是,如果你要把一个引用传递给一个对象,那么你需要使用标签的 ref 属性,而如果你要直接传递一个值,那么你应该使用 value 属性。
使用p:namespace实现xml配置:
首先引入命名空间:
接下来配置:
如果Bean的属性需要的是值,那么p:namespace方式和〈property〉注入方式只能使用一种,如果是引用,两种都写的话默认使用p:namespace注入的实例。
3.内部Bean
正如你所知道的 Java 内部类是在其他类的范围内被定义的,同理,inner beans 是在其他 bean 的范围内定义的 bean。因此在property或constructor-arg元素内 元素被称为内部bean,如下所示。
普通值也可以以一下方式注入:
4.注入集合:
<property>和<contructor-arg>的value和ref只能专递单一的值和实例引用。
为了传递多个值,如 Java Collection 类型 List、Set、Map 和 Properties,Spring 提供了四种类型的集合的配置元素,如下所示:
①<list>:它有助于连线,如注入一列值,允许重复
注入引用:
②<set>:它有助于连线一组值,但不能重复。
最后只剩下INDIA,Pakistan,USA
注入引用:
③<map>:它可以用来注入名称-值对的集合,其中名称和值可以是任何类型。
注入引用:
④<props>:它可以用来注入名称-值对的集合,其中名称和值都是字符串类型。
key也可以写成1,被当成字符串处理
注入空字符串:相当于helloChina.setMessage("");
注入空值:相当于helloChina.setMessage(null);