05.bean依赖注入的三种方式
1.概述
依赖注入 DI(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。简单的说,就是通过框架把持久层对象传入业务层,而不用我们自己去获取。
2.bean依赖注入方式
2.1 构造方法
- 在UserServiceImpl中创建有参构造
public class UserServiceImp implements UserService {
private UserDao userDao;
public UserServiceImp(UserDao userDao){
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
2. 配置Spring容器调用有参构造时进行注入
<bean id="userDao" class="com.weihong.dao.impl.UserDaoImpl" scope="prototype"></bean>
<bean id="userService" class="com.weihong.service.serviceImp.UserServiceImp" >
<constructor-arg name="userDao" ref="userDao" ></constructor-arg>
<!-- name:表示UserServiceImpl里UserDao对象的参数
ref:表示引用的是bean对象id为UserDao的对象
-->
</bean>
- 上面配置等价于
2.2 set方法
- 在UserServiceImpl中创建set方法
public class UserServiceImp implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
- 配置Spring容器调用set方法进行注入
<bean id="userDao" class="com.weihong.dao.impl.UserDaoImpl" scope="prototype"></bean>
<bean id="userService" class="com.weihong.service.serviceImp.UserServiceImp" >
<!--
name:表示UserServiceImpl里UserDao对象的参数
ref:表示引用的是bean对象id为UserDao的对象(引用对象的注入)
-->
<property name="userDao" ref="userDao"></property>
</bean>
等价于以下代码:
2.3 P命名空间注入
P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
- 定义约束头,引入p命名空间:
xmlns:p="http://www.springframework.org/schema/p"
- 修改注入方式:
<bean id="userDao" class="com.weihong.dao.impl.UserDaoImpl" scope="prototype"></bean>
<bean id="userService" class="com.weihong.service.serviceImp.UserServiceImp" p:userDao-ref="userDao">
</bean>
</bean>
3.bean依赖注入的数据类型
上面的注入都是注入Bean对象,除了对象的引用注入,普通数据类型和集合都可以在容器中进行注入。
注入数据的三种数据类型
- 普通数据类型
- 引用数据类型
- 集合数据类型
其中引用数据类型,上述已经介绍过了,下面将以set方法注入为例,演示普通数据类型和集合数据类型的注入。
3.1注入普通数据类型
- 普通数据类型
public class UserDaoImpl implements UserDao {
private String username;
private Integer age;
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 void save(){
System.out.println("age="+age+" username=" +username);
}
}
- 配置文件
<bean id="userDao2" class="com.weihong.dao.impl.UserDaoImpl" >
<!-- name:表示对象属性
value:表示为对象属性赋值
ref:表示引用数据对象的注入
-->
<property name="username" value="张三"></property>
<property name="age" value="17" ></property>
</bean>
- 测试结果
3.2注入集合数据类型
3.2.1List集合注入
public class UserDaoImpl implements UserDao {
private String username;
private Integer age;
private List<Object> userlist;
public List<Object> getUserlist() {
return userlist;
}
public void setUserlist(List<Object> userlist) {
this.userlist = userlist;
}
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 void save(){
System.out.println(" list = " + userlist);
}
}
appplicationContext.xml配置文件
<!-- user实体的bean对象-->
<bean id="user" class="com.weihong.domain.User">
<property name="userName" value="李白"></property>
<property name="age" value="26"></property>
</bean>
<!--List集合注入-->
<bean id="userDao3" class="com.weihong.dao.impl.UserDaoImpl" >
<property name="userlist" >
<list>
<!-- value:表示list集合第一个值为基本数据类型
ref:表示引用的数据对象user(也就是list的第二个值)
-->
<value>666</value>
<ref bean="user"></ref>
</list>
</property>
</bean>
测试类
@Test
public void test4(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) applicationContext.getBean("userDao3");
userDao1.save();
}
测试结果
3.2.2set集合注入
配置基本和list集合一样
public class UserDaoImpl implements UserDao {
private String username;
private Integer age;
private List<Object> userlist;
private Set<Object> set; //set集合
public void save(){
System.out.println(" list = " + userlist);
System.out.println(" set = " + set);
}
}
<!-- user实体的bean对象-->
<bean id="user" class="com.weihong.domain.User">
<property name="userName" value="李白"></property>
<property name="age" value="26"></property>
</bean>
<!--List集合注入-->
<bean id="userDao3" class="com.weihong.dao.impl.UserDaoImpl" >
<property name="userlist" >
<list>
<!-- value:表示list集合第一个值为基本数据类型
ref:表示引用的数据对象user(也就是list的第二个值)
-->
<value>666</value>
<ref bean="user"></ref>
</list>
</property>
<property name="set">
<set>
<value>我是set集合</value>
<ref bean="user"></ref>
</set>
</property>
</bean>
3.2.3Array数组注入
public class UserDaoImpl implements UserDao {
private String username;
private Integer age;
private List<Object> userlist;
private Set<Object> set; //set集合
private Object[] arrary; //数组
public void save(){
System.out.println(" list = " + userlist);
System.out.println(" set = " + set);
System.out.println(" arrary = " + Arrays.toString(arrary));//数组转换成字符串
}
}
<!-- user实体的bean对象-->
<bean id="user" class="com.weihong.domain.User">
<property name="userName" value="李白"></property>
<property name="age" value="26"></property>
</bean>
<!--List集合注入-->
<bean id="userDao3" class="com.weihong.dao.impl.UserDaoImpl" >
<!-- 数组注入-->
<property name="arrary">
<array>
<value>arrary</value>
<ref bean="user"></ref>
</array>
</property>
</bean>
3.2.4Map集合注入
public class UserDaoImpl implements UserDao {
private String username;
private Integer age;
private List<Object> userlist;
private Set<Object> set; //set集合
private Object[] arrary; //数组
private Map<String,Object> map;
public void save(){
System.out.println(" list = " + userlist);
System.out.println(" set = " + set);
System.out.println(" arrary = " + Arrays.toString(arrary));//数组转换成字符串
System.out.println(" map = "+ map );
}
}
<!-- user实体的bean对象-->
<bean id="user" class="com.weihong.domain.User">
<property name="userName" value="李白"></property>
<property name="age" value="26"></property>
</bean>
<!--List集合注入-->
<bean id="userDao3" class="com.weihong.dao.impl.UserDaoImpl" >
<!-- map集合-->
<property name="map">
<map>
<entry key="K1" value="叮当"></entry>
<entry key="K2" value-ref="user"></entry>
</map>
</property>
</bean>
3.2.5Properties配置注入
property和map类型,有key和value.
public class UserDaoImpl implements UserDao {
private String username;
private Integer age;
private List<Object> userlist;
private Set<Object> set; //set集合
private Object[] arrary; //数组
private Map<String,Object> map; //map集合
private Properties properties;
public void save(){
System.out.println(" list = " + userlist);
System.out.println(" set = " + set);
System.out.println(" arrary = " + Arrays.toString(arrary));//数组转换成字符串
System.out.println(" map = "+ map );
System.out.println(" properties = "+ properties );
}
}
<!-- user实体的bean对象-->
<bean id="user" class="com.weihong.domain.User">
<property name="userName" value="李白"></property>
<property name="age" value="26"></property>
</bean>
<!--List集合注入-->
<bean id="userDao3" class="com.weihong.dao.impl.UserDaoImpl" >
<!-- properties注入-->
<property name="properties" >
<props>
<prop key="K1">V1</prop>
<prop key="K2">V2</prop>
<prop key="K3">V3</prop>
</props>
</property>
</bean>
运行结果:
4.知识小结
- Spring的重点配置
<bean>标签:创建对象并放到spring的IOC容器
id属性:在容器中Bean实例的唯一标识,不允许重复
class属性:要实例化的Bean的全限定名
scope属性:Bean的作用范围,常用是Singleton(默认)和prototype
<constructor-arg>标签:属性注入
name属性:属性名称
value属性:注入的普通属性值
ref属性:注入的对象引用值
<property>标签:属性注入
name属性:属性名称
value属性:注入的普通属性值
ref属性:注入的对象引用值
<list>
<set>
<array>
<map>
<props>