Spring依赖注入
Spring框架的核心功能之一就是通过依赖注入的方式来管理Bean之间的依赖关系。
Spring常用的注入方式一般是三种:
- 构造函数注入
- 属性注入
- 集合属性注入
一、构造函数注入
基于构造函数注入
这里又分为两种情况:
1.1、 只有一个参数
只有一个参数又分为简单参数类型直接赋值(value)和引用赋值(ref)
简单参数类型就像是:字符串,数字等…直接用(value)
引用类型赋值则用(ref)
构造注入的标签:
<constructor-arg></constructor-arg>
//也可以单标签
<constructor-arg/>
(1).直接赋值(value)
例:
- 定义一个普通的java用户类
(只有一个参数可以通过构造注入的形式来设置)
- 由于只有一个参数可以直接进行赋值
这样我们调用user这个实例对象的get方法就可以返回value设置的值
如图:
(2).引用赋值(ref)
例:
- 创建一个名为IdCard的类
- User类创建IdCard类型的参数
- xml文件重新配置
- 输出结果
1.2、 有多个参数
如果有多个参数呢,我们可以根据名称或索引(name)、(index)
例:
- 我们更改User类为两个参数
(现在就不可以用第一种方式进行设置了)
- 用"name"属性指定设置多个值,也可以用"index"指定这设置多个值
结果正常输出
注:index索引是从 0 开始的
二、属性注入
很多情况下,我们不提供构造函数,构造函数的话比较麻烦,那么就可以用第二种方式:属性注入
2.1、基于setXXX函数的依赖注入
属性注入这里有一点:是需要提供对应的 “setXXX” 函数方法,提供好 “set” 方法就可以实现注入。
set方法举例图:
使用"property"进行注入
<property name="" value=""></property>
//也可以单标签
<property/>
例:
- 更改User类,设定"set"方法
- 使用"property"注入(属性注入)
- 结果:
2.2、使用 p-namespace 实现 xml 配置
如果你有许多属性都提供了 “set” 方法,那么在 xml 配置文件中使用 p-namespace 是非常方便的。
- 先在命名空间上引入: p
xmlns:p="http://www.springframework.org/schema/p"
- 这样property标签就可以合并到bean标签里
简单属性注入: p:属性名=""
复杂属性注入: p:属性名-ref=“spring中定义的bean”
<bean id="idCard" class="cn.netXiaobao.anno.IdCard">
<constructor-arg value="109009"></constructor-arg>
</bean>
<bean id="user" class="cn.netXiaobao.anno.User" p:name="王五" p:idCard-ref="idCard">
</bean>
</bean>
注意:在使用p名称空间时,Bean不能以构造方法进行,需使用set方法进行。
2.3、SPEL注入(Spring EL)
(1).PropertyPlaceholderConfigurer实现
注:这个现在不建议使用了,但是也需要了解;这种方法是在Spring版本较低的情况下使用的,现在已经废弃了
在开发中有时候有些参数我们并不想直接写成硬编码形式,我们更想写成配置文件形式,使其更加灵活。
Spring提供了PropertyPlaceholderConfigurer类和SPEL表达式能够很好的满足我们的需求。
SPEL读取配置文件应用
使用bean配置PropertyPlaceholderConfigurer
例:
-
创建properties文件
-
设置属性文件存放地址
<!-- 设置属性文件存放地址 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:beans.properties"/>
</bean>
- 引用注入Spring EL 表达式获取
<bean id="user" class="cn.netXiaobao.anno.User" p:idCard-ref="idCard">
<property name="name" value="${mes}"/>
</bean>
那么读取多个properties文件呢?
- property name 属性值改为"locations"
<!-- 设置属性文件存放地址 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- 单个配置文件 <property name="location" value="classpath:beans.properties"/> -->
<!-- 多个配置文件 -->
<property name="locations">
<array>
<value>classpath:beans.properties</value>
<value>classpath:beans2.properties</value>
</array>
</property>
</bean>
- 引用每个文件中的值对应设置的id
注:这种方法是在Spring版本较低的情况下使用的,现在已经废弃了
(2).使用context:property-placeholder配置
- 声明命名空间和schema
xmlns:context="http://www.springframework.org/schema/context"<!--命名空间-->
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd<!--地址-->
- 使用 context:property-placeholder
<!-- 配置context:property-placeholder -->
<context:property-placeholder location="classpath:db.properties,classpath:user.properties" />
备注:支持ant风格通配符
<context:property-placeholder location="classpath:*.properties" />
三、集合属性注入
如果你想传递多个值,如 Java Collection 类型 List、Set、Map 和 Properties,应该怎么做呢。为了处理这种情况,Spring 提供了四种类型的集合的配置元素,如下所示:
元素 | 描述 |
---|---|
<array> | 数组 |
<list> | list集合,允许重复。 |
<set> | set集合,但不能重复。 |
<map> | 它可以用来注入名称-值对的集合,其中名称和值可以是任何类型。 |
<props> | 它可以用来注入名称-值对的集合,其中名称和值都是字符串类型。 |
3.1、数组
使用<property>标签下的<array>标签 普通属性使用value,对象属性使用ref
<property name="bookArray">
<array>
<value>jsp</value>
<value>servlet</value>
<value>spring</value>
</array>
</property>
3.2、List集合
使用<property>标签下的<list>标签, 普通属性使用value,对象属性使用ref
<property name="list">
<list>
<value>jsp</value>
<value>servlet</value>
<value>spring</value>
</list>
</property>
3.3、Map集合
使用<map>标签下的<entry>
<property name="map">
<map>
<entry>
<key>jsp</key>
<value>2.0</value>
</entry>
<entry>
<key>spring</key>
<value>5.30</value>
</entry>
</map>
</property>
3.4、set集合
使用<set>标签下的<value>
<property name="set">
<set>
<value>jsp</value>
<value>servlet</value>
<value>spring</value>
</set>
</property>
3.5、Properties
使用<props>标签下的<prop key=""></prop>
<property name="properties">
<props>
<prop key="msg">你好</prop>
</props>
</property>
例:
-
创建CollectionBean类,并创建get和set方法
-
配置xml
-
遍历输出结果
集合类型的Bean进行注入(复用)
先思考一下,上面的如果我们想要数据进行复用该如何做呢?
将集合定义成Bean的形式
如果希望配置一个集合类型的Bean,而非一个集合类型的属性,则可以通过util命名空间进行配置。
在spring的配置文件中util命名空间类似于java.util包类对应,util命名空间提供了集合相关的配置,在使用命名空间前要导入util命名空间。
- 声明命名空间和schema
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
"
>
- Bean的配置
<util:map id="mapBean">
<entry key="jsp" value="35"/>
<entry>
<key></key>
<value>22</value>
</entry>
</util:map>
<util:list id="listBean">
<value><![CDATA[<张三>]]></value>
<value>李四</value>
</util:list>
<util:set id="setBean">
<value>苹果</value>
<value>香蕉</value>
</util:set>
<util:properties id="propBean">
<prop key="servlet">36</prop>
<prop key="jquery">55</prop>
</util:properties>
<bean id="collectionBean" class="cn.netXiaobao.anno.CollectionBean">
<property name="bookArray" ref="listBean"/>
<property name="list" ref="listBean"/>
<property name="map" ref="mapBean"/>
<property name="set" ref="setBean"/>
<property name="properties" ref="propBean"/>
</bean>
- 嵌入式写法
这一种方法也可以写,但是不建议,没必要,太繁琐了
<bean id="service">
<property name="map" >
<util:map map-class="java.util.HashMap"> <!-- 可以通过map-class显示指定Map的实现类 -->
<entry key="jsp" value="45"/>
<entry key="spring" value="86"/>
</util:map>
</property>
</bean>
四、属性值包含特殊符号
<!--属性值包含特殊符号
1、把<>进行转义 < >
2、把特殊符号内容写到CDATA <![CDATA[内容]]>
-->
<property name="address">
<value>
<![CDATA[<<湖北>>]]>
</value>
</property>