Spring依赖注入和简单demo
参考:
- Spring官方教程
- Spring中bean的四种注入方式
- 【狂神说Java】Spring5最新完整教程IDEA版通俗易懂
- 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 注意
- Set方法注入是主要的依赖注入方式!
- 在介绍针对不同数据类型的注入方式前,需要注意:使用set方法注入,必须要为属性提供
set()
方法,Spring容器就是通过调用bean
的set()
来为属性注入值的。而在xml文件中,使用set注入的方式就是通过property
标签。- 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 注意点
property
的name
属性,填写的不是属性的名称,而是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) {// ...}
}
这里假设ThingTwo
和ThingThree
没有继承上的相关性,因此没有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。应当使用name
或index
。
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
。确实,写法上一样,但是表示的含义却完全不同。property
的name
属性,是通过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相关推荐
- arg是什么函数_java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪...
前言 前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了...事后回家想了想这一块确 ...
- spring 依赖注入
Technorati 标记: spring,依赖注入,DI,ioc 平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的 ...
- Spring依赖注入:注解注入总结
更多11 spring 依赖注入 注解 java 注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.C ...
- spring依赖注入_Spring源码阅读:Spring依赖注入容器
依赖注入 依赖注入是Spring框架最核心的能力,Spring框架提供的AOP,WebMVC等其它功能都是以依赖注入容器作为基础构建的,Spring依赖注入容器类似于一个用于组装对象的框架内核,任何应 ...
- spring依赖注入_Spring依赖注入
spring依赖注入 介绍: 在设计良好的Java应用程序中,这些类应尽可能独立. 这样的设计提高了组件的可重用性. 它还使对各个组件进行单元测试变得更加容易. 依赖注入的概念促进了Java对象之间的 ...
- spring依赖注入_Spring依赖注入技术的发展
spring依赖注入 回顾Spring框架的历史,您会发现在每个发行版中实现依赖注入的方法越来越多. 如果您使用该框架已经超过一个月,那么在这篇回顾性文章中可能不会发现任何有趣的东西. 除了Scala ...
- Spring依赖注入技术的发展
回顾Spring框架的历史,您会发现实现依赖注入的方式在每个发行版中都在增加. 如果您使用该框架已经超过一个月,那么在这篇回顾性文章中可能不会发现任何有趣的东西. 除了Scala中的最后一个示例,没有 ...
- 【Spring】Spring 依赖注入之手动注入
文章目录 1.概述 2.依赖回顾 2.依赖对象的初始化方式 2.1 通过构造器设置依赖对象 2.2 通过set方法设置依赖对象 3.spring依赖注入 3.1 通过构造器注入 3.1.1 根据构造器 ...
- Spring 依赖注入的理解及三种注入方式
Spring 依赖注入概念和三种注入方式(理解及应用) 什么是注入 要了解Spring的三种注入方式首先前提是得先了解一下什么是注入,相信很多人对这个概念都是模糊不清的,网上的解释是这样的: 依赖注入 ...
- spring依赖注入原理详解(转载)
spring依赖注入原理详解----转载 所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它.所 ...
最新文章
- 【转】PendingIntent的总结
- win8计算机安全模式,安全模式,教您Win8怎么进入安全模式
- 决策树算法(三)——计算香农熵
- sed替换每行最后一个字符
- mac 查看端口_黑客克星养成记 系列二:MAC-Flooding原理及解决方案
- KitKat系统发现BUG:付费输入法更新后自动停用
- 如何使用SetTimer MFC 够详细
- php矢量瓦片,矢量瓦片相关计算函数
- 服务器位置缩写,服务器地区缩写
- python3 Crypto使用出现的问题
- C语言控制台美化教程
- 统一身份认证系统方案
- 小菜鸟的Python笔记002:如何识别Word文档中的复选框
- Python基础学习笔记-第一章
- 使用lxml爬取豆瓣电影排行榜
- python print用法举例,Python2和Python3中print的用法示例总结
- CPU卡PSAM卡 响应指令
- 4x root 红米_红米手机4x如何获取root权限?
- OTSU(最大类间方差法、大津算法)
- CF869A The Artful Expedient 结论题+数论
热门文章
- pacman 查询_ArchLinux的pacman命令详解
- JS十六进制转浮点、字符串转为ArrayBuffer、ArrayBuffer转16进制字符串、16进制转10进制、crc校验位、十六进制转中文字符串(小程序、浏览器)、十六进制字符串转ascall字串
- lighttp 配置php扩展包,Lighttpd配置
- ie浏览器html状态栏隐藏,我的IE浏览器忽然上面的菜单栏及地址栏都不见了
- C#版OPCClient代码总结
- 针对笔记本双显卡安装ubuntu16.04双系统,开机只显示背景图解决办法
- python实现ORC/文字识别之pytesseract
- N-gage QD等S60 V1.2机型C盘减肥80K的办法(超越3600KB)
- laravel5.5.50之权限(laravel-permissions)的使用
- KDD cup 2017 高速公路收费站交通流量预测 中文翻译(转载)