05.bean依赖注入的三种方式

1.概述

依赖注入 DI(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。

在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。

那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。简单的说,就是通过框架把持久层对象传入业务层,而不用我们自己去获取。

2.bean依赖注入方式

2.1 构造方法

  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方法

  1. 在UserServiceImpl中创建set方法
public class UserServiceImp implements UserService {
    private UserDao userDao;
    
    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }

    @Override
    public void save() {
        userDao.save();
    }
  1. 配置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>

等价于以下代码:

java中工具类注入bean bean的注入_spring

2.3 P命名空间注入

P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:

  1. 定义约束头,引入p命名空间:
xmlns:p="http://www.springframework.org/schema/p"
  1. 修改注入方式:
<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对象,除了对象的引用注入,普通数据类型和集合都可以在容器中进行注入。

注入数据的三种数据类型

  1. 普通数据类型
  2. 引用数据类型
  3. 集合数据类型

其中引用数据类型,上述已经介绍过了,下面将以set方法注入为例,演示普通数据类型和集合数据类型的注入。

3.1注入普通数据类型

  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);
    }
}
  1. 配置文件
<bean id="userDao2" class="com.weihong.dao.impl.UserDaoImpl" >
<!--        name:表示对象属性
            value:表示为对象属性赋值
            ref:表示引用数据对象的注入
-->
        <property name="username" value="张三"></property>
        <property name="age" value="17" ></property>
    </bean>
  1. 测试结果

java中工具类注入bean bean的注入_spring_02

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();
    }

测试结果

java中工具类注入bean bean的注入_bean_03

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>

运行结果:

java中工具类注入bean bean的注入_spring_04

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>