上一篇文章链接戳我们将Spring的IOC基本使用已经讲的差不多了,下面我们讲一下Spring的依赖注入
DI依赖注入
什么是依赖?
一个组件在工作(执行)期间用到了另外一个组件,称为依赖。
什么是依赖注入?
软件组件有依赖关系,在组件工作时候将依赖的组件注入到对象中称为依赖注入。简单点来说就是将某个对象需要的对象或者基本属性赋值。
不明白的话我们直接看代码。
还是使用User这个实体类,但是我们在创建一个Phone类,代表电话号码对象。
package entity;
public class Phone {
private String phone = "12345678";
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "Phone{" +
"phone='" + phone + '\'' +
'}';
}
}
然后将这个Phone对象加到User的属性中,直接粘的全部代码
package entity;
public class User {
private String userName;
private Integer age;
private String sex;
private Phone phone;//Phone对象
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", phone=" + phone +
'}';
}
}
如果我想在创建一个User对象时,给name和Phone赋初始值应该怎么做?有许多办法可以去做到,Spring就给我们提供了DI功能,可以在组件有依赖关系时候,将组件注入到目标位置。
Spring提供了property标签,用于依赖注入,该标签有三个属性,name是你需要注入的属性名,ref是注入的对象的id名,value是基本类型的注入。
xml配置文件,先将Phone实体类交给Spring管理,在创建User的bean组件,在该组件中加入property标签。
<!--Phone实体类对象-->
<bean id="phone" lazy-init="true" class="entity.Phone"/>
<!-- property标签用于注入Bean属性 Spring会在初始化对象时候,自动调用其set方法将值或对象注入 -->
<bean id="userProperty" lazy-init="true" class="entity.User">
<!--ref用于注入对象-->
<property name="phone" ref="phone"/>
<!-- value用于注入基本值:基本类型和字符串 -->
<property name="userName" value="csdn"/>
</bean>
这样配置文件就写好了,我们User类初始化时会将phone和userName属性进行赋值。写下测试方法
@Test
public void userProperty(){
User user = cpx.getBean("userProperty",User.class);
System.out.println(user);
}
测试结果
User{userName='csdn', age=null, sex='null', phone=Phone{phone='12345678'}}
从结果就可以看出userName和phone在创建时已经被初始化。
注意:Spring容器在进行依赖注入时,靠的是实体类的setter方法!!
Spring注入集合和数组
我们在上面可以将基本类型和对象注入,下面我们来讲一下集合和数组的注入。Spring提供了property的子标签,就不进行测试了,直接上代码。
- 注入List集合
<property name="xxx">
<list>
<value>xxx</value>
<value>xxx</value>
<--如果list集合为对象,可以使用ref属性标签或者bean组件-->
<ref bean="x"/>
<bean class="xx"/>
</list>
</property>
- 注入set集合
<property name="xxx">
<set>
<value>1</value>
<value>2</value>
</set>
</property>
- 注入array数组
<property name="xxx">
<array>
<value>xxx</value>
<value>xxx</value>
</array>
</property>
- 注入map集合
<property name="xxx">
<map>
<entry key="xxx">
<value>xxx</value>
</entry>
<entry key="xxx">
<value>xxx</value>
</entry>
</map>
</property>
Spring自动注入
我们在使用Spring注入时写许多的property标签,也挺麻烦的,Spring就提供了自动注入功能,不用再去写property标签,Spring会自动去查找类型或者名字匹配的组件进行注入。注意:这里的自动注入依赖的不在是setter方法,而是反射!!!
- 按照名称注入
注意事项:被注入的bean属性名和bean组件的id名要一致,在bean组件上加上属性autowired=“byName”,Spring会在启动时根据名字找出对应的组件进行注入
<!--Phone实体类对象-->
<bean id="phone" lazy-init="true" class="entity.Phone"/>
<!--根据名称自动注入-->
<bean id="userAutowiredByName" lazy-init="true" class="entity.User" autowire="byName"/>
- 按照类型注入
注意事项:设置被注入的Bean属性 autowire=“byType”,Spring启动时候根据被注入的的Bean的属性类型查找类型兼容的Bean组件,如果找到就进行自动注入,找不到就取消。 如果找到两个以上的Bean组件则报错误!!!
<!--Phone实体类对象-->
<bean id="phone" lazy-init="true" class="entity.Phone"/>
<!--根据类型自动注入-->
<bean id="userAutowiredByType" lazy-init="true" class="entity.User" autowire="byType"/>
Spring的DI依赖注入基本配置使用基本就这些,还有一些零散的知识点说一下。
Spring读取properties文件
我们在配置数据库连接时,可能会写在工具类中,也可能会写在jdbc.properties文件中,我们在连接数据库时的BasicDataSource类也可以交给Spring进行管理。
<!-- 利用Spring管理数据库连接池 -->
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="xxx"/>
<property name="url" value="xxx"/>
<property name="username" value="xxx"/>
<property name="password" value="xxx"/>
<property name="maxActive" value="xxx"/>
<property name="initialSize" value="xxx"/>
</bean>
如果我们的数据库连接配置是写在properties文件中,我们可以先读取properties文件
<!-- Spring 在启动时候读取jdbc.properties文件为内存Bean对象,对象类型是Properties对象的ID是jdbc -->
<util:properties id="jdbc" location="classpath:jdbc.properties"/>
读取完了我们应该怎样将其配置的值放到注入到数据库连接池对象中?这里涉及到了Spring表达式。
语法:#{BeanID.Bean属性}
例子:
- 读取bean属性 #{user.name}
- 读取list集合 #{list[0]}
- 读取数组 #{array[0]}
- 读取Map #{map.xxx} 或者 #{map[‘xxx’]}
- 读取properties文件 #{jdbc.xxx}
这样我们就可以完整的写一遍读取properties文件的配置文件代码
<util:properties id="jdbc" location="classpath:jdbc.properties"/>
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="#{jdbc.driver}"/>
<property name="url" value="#{jdbc.url}"/>
<property name="username" value="#{jdbc.username}"/>
<property name="password" value="#{jdbc.password}"/>
<property name="maxActive" value="#{jdbc.maxActive}"/>
<property name="initialSize" value="#{jdbc.initialSize}"/>
</bean>
这几篇文章讲的是Spring最基本的使用,xml配置文件写的很繁琐,简化写法与Spring的注解等用法可以参考文章Spring的基本使用。