目录
四、 Spring 的依赖注入(DI)
4.1 相关介绍
依赖注入:Dependency Injection。它是spring框架核心ioc的具体实现。
我们的程序在编写时,通过控制反转,把对象的创建交给了spring,但是代码中不可能出现没有依赖的情况。ioc解耦只是降低他们的依赖关系,但不会消除。那这种业务层和持久层的依赖关系,在使用spring之后,就让spring来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。 这就是依赖注入。
依赖注入:
能注入的数据:
- 基本类型和String类型(值的注入)
- 其他bean对象类型(在配置文件中或者注解配置过的bean)(对象的注入)
- 复杂类型/集合类型(集合的注入)
能注入的方式:
- 使用构造函数提供
- 使用set方法提供(使用p名称空间注入)(用的最多)
- 使用注解提供
4.2 构造方法注入
applicationContext.xml
<!--构造函数注入:
使用的标签:constructor-arg
标签出现的位置:bean标签的内部
标签中的属性
type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
name:用于指定给构造函数中指定名称的参数赋值 常用的
=============以上三个用于指定给构造函数中哪个参数赋值===============================
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
优势:
在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
弊端:
改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
-->
<bean id="accountService" class="com.cpz.service.impl.AccountService_constructor">-->
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="age" value="22"></constructor-arg>
<constructor-arg name="birthday" ref="birthday"></constructor-arg>
</bean>
<bean id="birthday" class="java.util.Date">
AccountServiveImpl.java
package com.cpz.service.impl;
import com.cpz.service.AccountService;
import java.util.Date;
public class AccountService_constructor implements AccountService {
private String name;
private Integer age;
private Date birthday;
public AccountService_constructor(){
}
public AccountService_constructor(String name,Integer age,Date birthday){
this.name = name;
this.age = age;
this.birthday = birthday;
}
public void saveAccount() {
System.out.println("saveAccount方法执行了....");
System.out.println("name: " + name + " age: " + age + " birthday: " + birthday);
}
}
Main.java
package com.cpz.main;
import com.cpz.service.AccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = (AccountService) ac.getBean("accountService");
accountService.saveAccount();
}
}
4.3 set方法注入
applicationContext.xml
<!-- set方法注入
涉及的标签:property
出现的位置:bean标签的内部
标签的属性
name:用于指定注入时所调用的set方法名称
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
优势:
1:使用set方法创建对象时没有明确的限制,可以直接使用默认构造函数;
2:使用set方法注入值或者对象,需要哪个属性只需要注入哪个属性
-->
<bean id="accountService" class="com.cpz.service.impl.AccountService_set">
<property name="name" value="李四"></property>
<property name="age" value="21"></property>
<property name="birthday" ref="birthday"></property>
</bean>
<bean id="birthday" class="java.util.Date"></bean>
AccountService_set.java
package com.cpz.service.impl;
import com.cpz.service.AccountService;
import java.util.Date;
public class AccountService_set implements AccountService {
private String name;
private Integer age;
private Date birthday;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public void saveAccount() {
System.out.println("saveAccount方法执行了....");
System.out.println("name: " + name + " age: " + age + " birthday: " + birthday);
}
}
4.4 使用p名称空间注入数据(本质还是set注入)
applicationContext.xml
引入p名称空间:xmlns:p="http://www.springframework.org/schema/p"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountService" class="com.cpz.service.impl.AccountService_set" p:name="王五" p:age="20" p:birthday-ref="birthday"></bean>
<bean id="birthday" class="java.util.Date"></bean>
注意:需要对属性提供 set 方法,方可实现注入
4.5 注入集合属性(复杂类型)
AccountServiceImpl.java
public class AccountServiceImpl implements AccountService {
Object[] arrays;
List<Object> list;
Set<Object> set;
Map<String,Object> map;
Properties properties;
public void setArrays(Object[] arrays) {
this.arrays = arrays;
}
public void setList(List<Object> list) {
this.list = list;
}
public void setSet(Set<Object> set) {
this.set = set;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void saveAccount() {
System.out.println("saveAccount方法执行了....");
System.out.println("arrays: " + Arrays.toString(arrays) + " list: " + list + " set: " + set + " map: " + map + " properties: " + properties);
}
}
applicationContext.xm
<!-- 复杂类型的注入/集合类型的注入
用于给List结构集合注入的标签:
list array set
用于个Map结构集合注入的标签:
map props
结构相同,标签可以互换
-->
<bean id="birthday" class="java.util.Date"></bean>
<bean id="accountService" class="com.cpz.service.impl.AccountServiceImpl">
<property name="arrays">
<array>
<value>赵六</value>
<value>25</value>
<ref bean="birthday"></ref>
</array>
</property>
<property name="list">
<list>
<value>哈哈</value>
<value>嘿嘿</value>
<value>呵呵</value>
</list>
</property>
<property name="set">
<set>
<value>a</value>
<value>b</value>
<value>c</value>
</set>
</property>
<property name="map">
<map>
<entry key="username" value="chi"></entry>
<entry key="password" value="123"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="driver">com.mysql.jdbc.Driver</prop>
<prop key="url">jdbc:mysql:///test</prop>
<prop key="username">root</prop>
<prop key="password">1234</prop>
</props>
</property>
</bean>
4.6 在 Service 中,注入 Dao
applicationContext.xml
<bean id="accountService" class="com.cpz.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.cpz.dao.impl.AccountDaoImpl"></bean>
在AccountServiceImpl上提供set方法
public class AccountServiceImpl implements AccountService {
AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
public void saveAccount() {
System.out.println("saveAccount方法执行了....");
accountDao.saveAccount();
}