参考:

  1. Spring官方教程
  2. Spring中bean的四种注入方式
  3. 【狂神说Java】Spring5最新完整教程IDEA版通俗易懂
  4. Spring官方教程

1. 定义

1.1 概念

依赖注入 Dependency Injection
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性,由容器来注入

1.2 分类

Spring依赖注入( Dependency Injection)有两大方式:1. 构造器注入(Constructor-based Dependency Injection)2. Set方法注入(Setter-based Dependency Injection)。此外还有c/p命名空间注入,但其本质还是这两大方式。需要区分的是,一个是在构造对象的时候进行注入,一个是在构造完对象后使用set方法进行注入。

1.3 注意

  1. Set方法注入是主要的依赖注入方式!
  2. 在介绍针对不同数据类型的注入方式前,需要注意:使用set方法注入,必须要为属性提供set()方法,Spring容器就是通过调用beanset()来为属性注入值的。而在xml文件中,使用set注入的方式就是通过property标签。
  3. Spring在创建Bean(加载XML配置文件)的时候,就已经帮我们把Spring容器(ApplicationContext)管理的对象初始化了。在使用ApplicationContext.getBean()的时候,获取的bean都是同一个对象:Spring框架中的Bean,或者说组件,获取实例的时候都是默认单例模式,这是在多线程开发的时候需要尤其注意的地方。

2. Set方法注入

2.1 pojo

现在假如有一个Student类:

public class Student {private String name;private String Age;private Address address;private String[] books;private List<String> hobbies;private Map<String, String> cards;private Set<String> games;private String wife;private Properties info;// 每个属性都有相应的get/set方法...
}

2.2 XML配置文件

那么相对应的xml配置文件应该是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="address" class="pojo.Address"/><bean id="student" class="pojo.Student"><!-- 1. 普通值注入,value --><property name="name" value="Xiaoming" /><!-- 注意这里'age'是小写 --><property name="age" value="15" /><!-- 2. Bean注入,ref --><property name="address" ref="address" /><!-- 3. 数组注入,array --><property name="books" ><array><!-- 如果是value="",需要双引号;如果是<value>xxx</value>,中间不需要双引号 --><value>指环王1</value><value>指环王2</value><value>"指环王3"</value></array></property><!-- 4. List注入,list --><property name="hobbies" ><list><value>健身</value><value>学习</value></list></property><!-- 5. Map注入,map --><property name="cards" ><map><entry key="id" value="123" /><entry key="studentid" value="321" /></map></property><!-- 6. Set注入,set --><property name="games"><set><value>CF</value><value>csgo</value></set></property><!-- 7. null注入 --><property name="wife"><null/></property><!-- 8. Properties注入 --><property name="info"><props><prop key="age">12</prop><prop key="sex">Male</prop></props></property></bean>
</beans>

2.3 注意点

propertyname属性,填写的不是属性的名称,而是set方法去除"set",然后将第一个字符小写后的结果。比如我特意把name的第一个字母设置成小写,Age的第一个字母设置成大写,他们的set方法都是setName()setAge(),根据上面的注意点,在xml中写属性的name时,都得统一使用小写。

3. 构造器注入(四种方式)

3.1 根据引用

这里的引用是指除了Java基本类型之外的类型,并且已经在.xml文件中注册过的bean。

ThingOne

package x.y;public class ThingOne {public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {// ...}
}

这里假设ThingTwoThingThree没有继承上的相关性,因此没有ambiguity,无需显式地表明构造器参数下标或类型。

XML

<beans><bean id="beanOne" class="x.y.ThingOne"><constructor-arg ref="beanTwo"/><constructor-arg ref="beanThree"/></bean><bean id="beanTwo" class="x.y.ThingTwo"/><bean id="beanThree" class="x.y.ThingThree"/>
</beans>

3.2 根据类型(不建议使用)

前面的例子使用了reference,需要清楚的知道引用的是什么类型。在使用基本类型的时候,需要显式表明参数的类型,避免ambiguity。需要注意的是,类型并不需要按构造器中声明的顺序编写。然而根据类型来注入还是会引起ambiguity,比如当构造器有多个相同类型的参数时,将会有ambiguity。应当使用nameindex

ExampleBean

package examples;public class ExampleBean {// Number of years to calculate the Ultimate Answerprivate final int years;// The Answer to Life, the Universe, and Everythingprivate final String ultimateAnswer;public ExampleBean(int years, String ultimateAnswer) {this.years = years;this.ultimateAnswer = ultimateAnswer;}
}

XML

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

3.3 根据参数名(最好用,最直接)

XML

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

有人看完之后,可能会觉得这里的配置和set注入时的配置几乎一样,除了一个使用property,一个使用constructor-arg。确实,写法上一样,但是表示的含义却完全不同。propertyname属性,是通过set()方法的名称得来;而constructor-arg的name,则是构造器参数的名称。

请记住,要使其开箱即用,您的代码必须在启用调试标志的情况下编译,以便Spring可以从构造函数中查找参数名。如果不能或不想使用调试标志编译代码,可以使用@ConstructorProperties JDK注释显式地命名构造函数参数。样例类应该如下所示:

ExampleBean

package examples;public class ExampleBean {// Fields omitted@ConstructorProperties({"years", "ultimateAnswer"})public ExampleBean(int years, String ultimateAnswer) {this.years = years;this.ultimateAnswer = ultimateAnswer;}
}

3.4 根据下标

XML

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

使用下标可以很好地解决,构造器有两个同样类型的参数的情况。
注意:根据下标注入,下标从0开始。使用上面的方式配置,若赋值的类型与参数的类型不一致,将会在容器初始化bean的时候抛出异常。如果bean存在多个参数数量一样的构造器,Spring容器会自动找到类型匹配的那个进行调用。假如两个构造器都满足传入的value的类型,换言之,若存在多个构造器匹配bean的定义,Spring容器总是使用最后一个满足条件的构造器

4. p/c命名空间

p-namespace里的p对应的是properties,也对应着Set方法注入
c-namespace里的c对应的是constructor,也对应着构造器注入
p和c的命名空间注入简而言之就是在tag里直接注入属性(properties),说到底都是为了简化代码

“The p-namespace lets you use the bean element’s attributes (instead of nested elements) to describe your property values collaborating beans, or both.”

4.1 p-namespace

不能直接用,需要导入xml约束:
xmlns:p="http://www.springframework.org/schema/p"

User

public class User {private String name;private int age;private Address address;// getters and setters:// ...
}

XML

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="address" class="pojo.Address"/><bean id="user" class="pojo.User"p:name="Xiaoming"p:age="18"p:address-ref="address"/></beans>

4.2 c-namespace

不能直接用,需要导入xml约束:
xmlns:c="http://www.springframework.org/schema/c"

User

// 需要无参构造
public User() {}// 需要有参构造
public User(String name, int age, Address address) {this.name = name;this.age = age;this.address = address;
}

XML

<bean id="user2" class="pojo.User"c:name="Hello"c:age="28"c:address-ref="address" />

Spring依赖注入和简单demo相关推荐

  1. arg是什么函数_java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪...

    前言 前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了...事后回家想了想这一块确 ...

  2. spring 依赖注入

    Technorati 标记: spring,依赖注入,DI,ioc 平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的 ...

  3. Spring依赖注入:注解注入总结

    更多11 spring 依赖注入 注解 java 注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.C ...

  4. spring依赖注入_Spring源码阅读:Spring依赖注入容器

    依赖注入 依赖注入是Spring框架最核心的能力,Spring框架提供的AOP,WebMVC等其它功能都是以依赖注入容器作为基础构建的,Spring依赖注入容器类似于一个用于组装对象的框架内核,任何应 ...

  5. spring依赖注入_Spring依赖注入

    spring依赖注入 介绍: 在设计良好的Java应用程序中,这些类应尽可能独立. 这样的设计提高了组件的可重用性. 它还使对各个组件进行单元测试变得更加容易. 依赖注入的概念促进了Java对象之间的 ...

  6. spring依赖注入_Spring依赖注入技术的发展

    spring依赖注入 回顾Spring框架的历史,您会发现在每个发行版中实现依赖注入的方法越来越多. 如果您使用该框架已经超过一个月,那么在这篇回顾性文章中可能不会发现任何有趣的东西. 除了Scala ...

  7. Spring依赖注入技术的发展

    回顾Spring框架的历史,您会发现实现依赖注入的方式在每个发行版中都在增加. 如果您使用该框架已经超过一个月,那么在这篇回顾性文章中可能不会发现任何有趣的东西. 除了Scala中的最后一个示例,没有 ...

  8. 【Spring】Spring 依赖注入之手动注入

    文章目录 1.概述 2.依赖回顾 2.依赖对象的初始化方式 2.1 通过构造器设置依赖对象 2.2 通过set方法设置依赖对象 3.spring依赖注入 3.1 通过构造器注入 3.1.1 根据构造器 ...

  9. Spring 依赖注入的理解及三种注入方式

    Spring 依赖注入概念和三种注入方式(理解及应用) 什么是注入 要了解Spring的三种注入方式首先前提是得先了解一下什么是注入,相信很多人对这个概念都是模糊不清的,网上的解释是这样的: 依赖注入 ...

  10. spring依赖注入原理详解(转载)

    spring依赖注入原理详解----转载 所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它.所 ...

最新文章

  1. 【转】PendingIntent的总结
  2. win8计算机安全模式,安全模式,教您Win8怎么进入安全模式
  3. 决策树算法(三)——计算香农熵
  4. sed替换每行最后一个字符
  5. mac 查看端口_黑客克星养成记 系列二:MAC-Flooding原理及解决方案
  6. KitKat系统发现BUG:付费输入法更新后自动停用
  7. 如何使用SetTimer MFC 够详细
  8. php矢量瓦片,矢量瓦片相关计算函数
  9. 服务器位置缩写,服务器地区缩写
  10. python3 Crypto使用出现的问题
  11. C语言控制台美化教程
  12. 统一身份认证系统方案
  13. 小菜鸟的Python笔记002:如何识别Word文档中的复选框
  14. Python基础学习笔记-第一章
  15. 使用lxml爬取豆瓣电影排行榜
  16. python print用法举例,Python2和Python3中print的用法示例总结
  17. CPU卡PSAM卡 响应指令
  18. 4x root 红米_红米手机4x如何获取root权限?
  19. OTSU(最大类间方差法、大津算法)
  20. CF869A The Artful Expedient 结论题+数论

热门文章

  1. pacman 查询_ArchLinux的pacman命令详解
  2. JS十六进制转浮点、字符串转为ArrayBuffer、ArrayBuffer转16进制字符串、16进制转10进制、crc校验位、十六进制转中文字符串(小程序、浏览器)、十六进制字符串转ascall字串
  3. lighttp 配置php扩展包,Lighttpd配置
  4. ie浏览器html状态栏隐藏,我的IE浏览器忽然上面的菜单栏及地址栏都不见了
  5. C#版OPCClient代码总结
  6. 针对笔记本双显卡安装ubuntu16.04双系统,开机只显示背景图解决办法
  7. python实现ORC/文字识别之pytesseract
  8. N-gage QD等S60 V1.2机型C盘减肥80K的办法(超越3600KB)
  9. laravel5.5.50之权限(laravel-permissions)的使用
  10. KDD cup 2017 高速公路收费站交通流量预测 中文翻译(转载)