天天看点

Spring DI(依赖注入)之xml配置

前言

​ 通过IOC控制反转的学习,我们已经知道了如果将类的创建进行控制反转,并使用Spring容器来管理;也知道了如何创建Spring容器,从中获取Bean。

​ 但是当我们一个类中定义了其他基本类型或引用类型的属性,那么怎么在从Spring容器中获取Bean的同时,也能够让Bean中的属性赋上值呢?

​ 这就是我们要学习的DI依赖注入。

依赖注入简介

当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。

但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。

简而言之,依赖注入就是在Spring容器中获取一个Bean的同时,让这个Bean中需要的属性、参数也能获取到对应的值。

依赖注入的方式

  1. 通过构造方法进行注入
  2. 通过set方法进行注入

DI入门案例

  • 通过构造方式进行注入
    • User实体类
      /**
       * 用户实体类
       */
      public class User {
      
          private String name; //姓名
          private int age; //年龄
      
          public User(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
                 
    • applicationContext配置文件
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             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">
          
          <!--
      		配置User
      		id:表示此bean的唯一标识
      		class:指定要创建对象的类的字节码对象
      	-->
          <bean id="user" class="com.itheima.entity.User">
              <!--
      			当通过构造方法注入时,使用constructor-arg标签
      			name:对应构造方法的参数
      			value:对name指定的参数进行赋值,无论字符和数字都用双引号
      		-->
              <constructor-arg name="name" value="张三"/>
              <constructor-arg name="age" value="25"/>
          </bean>
      </beans>
                 
    • 测试代码
      public class Test {
      
          public static void main(String[] args) {
              //加载配置文件,创建Spring容器
              ApplicationContext context = new
                      ClassPathXmlApplicationContext("applicationContext.xml");
              //获取Bean
              User user = context.getBean("user", User.class);
              System.out.println(user);
          }
      }
                 
    • 结果
      Spring DI(依赖注入)之xml配置
  • 通过set方法注入
    • User1实体类
      /**
       * 用户实体类
       */
      public class User1 {
      
          private String name; //姓名
          private int age; //年龄
      
          public void setName(String name) {
              this.name = name;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
                 
    • applicationContext.xml配置文件
      <!--
      	配置User1
      	id:表示此bean的唯一标识
      	class:指定要创建对象的类的字节码对象
      -->
      <bean id="user1" class="com.itheima.entity.User1">
           <!--
             当通过set方法注入时,使用property标签
             name:对应set方法的方法名(例如setName方法,去掉setN  -> 对应的是:name)
             value:对name指定的参数进行赋值,无论字符和数字都用双引号
       	 -->
          <property name="name" value="李四"/>
          <property name="age" value="56"/>
      </bean>
                 
    • 测试类
      public class Test1 {
      
          public static void main(String[] args) {
              //加载配置文件,创建Spring容器
              ApplicationContext context = new
                      ClassPathXmlApplicationContext("applicationContext.xml");
              //获取Bean
              User1 user1 = context.getBean("user1", User1.class);
              System.out.println(user1);
          }
      }
                 
    • 结果
      Spring DI(依赖注入)之xml配置

多种类型依赖注入

属性类型分类

  • 基本类型包装类,比如 Integer、Double、Boolean;
  • 字符串类型,比如 String;
  • 集合类型,比如 list、set、map 。
  • 类类型,比如 其余定义的 java 类;

代码数据准备

//用户实体类
public class User {

private Integer id;
private String name;
private Object [] array;
private List    list;
private Map  map;
//省略get和set方法

}

           

以下根据这个实体类来演示各个属性类型的依赖注入。

基本类型和字符串类型

​ 对于基本类型和字符串类型,在 xml 的配置文件中,通过 value 属性即可以赋值,在入门案例中已经使用。

数组类型

  • 配置文件编写
    <!-- 
    	数组的属性注入
    	id:设置bean的唯一标识,获取Bean的时候根据id进行获取
    	class:要创建对象的类的字节码对象,对象创建后会由Spring进行管理
     -->
    <bean id="user" class="com.offcn.entity.User">
    
    	<property name="array">
    		<array>
    			<value>tom</value>
    			<value>jerry</value>
    		</array>
    	</property>
    </bean>
               
  • 配置解释
    • property 中的 name Java类中数组的set方法的名字 如:SetArray 去掉Set ,A小写,得到array;name只与set方法有关。 property表示通过set方法注入。
    • array 标签是固定的,不能变化,表示属性是一个数组,所以加在了 property 的属性内部。
    • value 表示数组中的值,因为数组可以存储多个值,所以每一个数组的值,通过一个 value 标签声明。

集合类型

  • list集合依赖注入
    • 配置文件编写
      <!-- 集合的属性注入 -->
      <bean id="user" class="com.offcn.entity.User">
      	<property name="list">
      		<list>
      			<value>笑傲江湖</value>
      			<value>侠客行</value>
      			<value>连城诀</value>
      		</list>
      	</property>
      </bean>
                 
    • 配置解释
      • property 中的 name 是 java 类中List集合的set方法名,表示通过set方法注入,name只与set方法名有关。
      • list 标签是固定的,不能变化,表示属性是一个 list 集合 ,所以加在了 property 的属性内部
      • value 表示集合中的值,因为集合可以存储多个值,所以每一个集合中的值,通过一个 value 标签声明.
    • List集合与Set集合相同
  • map集合依赖注入
    • 配置文件编写
      <bean id="user" class="com.offcn.entity.User">
      	<property name="map">
      		<map>
      			<entry key="小亮" value="小路"></entry>
      			<entry key="文同学" value="伊利姐"></entry>
      		</map>
      	</property>
      </bean>
                 
    • 配置解释
      • property 中的 name 是 java 类中List集合的set方法名,表示通过set方法注入,name只与set方法名有关。
      • map 标签是固定的,不能变化,表示属性是一个 map 集合 ,所以加在了 property 的属性内部。
      • entry 标签固定表示 map 中的一对键值对,map 也可以存储多对,所以 key 表示键值对的键,value 表示键值对的值。

类类型

​ 一个类中依赖另一个类的情况;就像我们编写三层架构的时候,表现层依赖业务逻辑层,业务逻辑层依赖数据访问层;只有数据访问层与数据库打交道。

​ 以下我们就模拟一下 业务逻辑层依赖数据访问层的情况;也就是说在逻辑层中,有数据访问层类的成员变量属性。

​ 数据准备

  • 数据访问层 UserDao
    /**
     * 模拟关于用户的数据访问层
     */
    public class UserDao {
    
        /**
         * 模拟保存用户
         */
        public void saveUser() {
            System.out.println("我是UserDao中的保存用户的方法!");
        }
    }
    
               
  • 业务逻辑层 UserService
    /**
     * 模拟用户业务逻辑层
     */
    public class UserService {
    
        //依赖数据访问层
        private UserDao userDao;
    
        //提供set方法,方便依赖注入
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
    
        /**
         * 保存用户方法
         */
        public void saveUser() {
            //调用数据访问层的保存用户方法
            userDao.saveUser();
        }
    }
               
  • 编写Spring配置文件
    <?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:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="
            http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
    
            <!--先要配置数据访问层UserDao-->
            <bean id="userDao" class="com.my.Dao.UserDao"/>
            
            <!--配置业务逻辑层-->
            <bean id="userService" class="com.my.service.UserService">
                    <!--
                            通过Set方法注入UserDao
                            name:对应UserService类中的Set方法的名字
                            ref:(reference:引用),表示这个属性引用上面配置的UserDao的id,这样就能实现类类型的注入
                    -->
                    <property name="userDao" ref="userDao"/>
            </bean>
    </beans>
               
  • 配置说明
    • property:表示通过Set方法进行依赖注入。
    • name:对应UserService类中的Set方法的名字,name只与Set方法名相关。
    • ref:表示这个属性引用上面配置的UserDao的id,这样就能实现类类型的注入,当我们从Spring中获取UserServices示例对象的时候,Spring会将UserServices对象依赖的UserDao实例对象,一并完成依赖注入。
  • 测试代码
    /**
     * 测试类
     */
    public class UserServiceTest {
    
        /**
         * 保存用户方法测试
         */
        @Test
        public void userSaveTest() {
            //创建spring容器,参数指定spring配置文件的全名
            ApplicationContext context = new
                    ClassPathXmlApplicationContext("applicationContext.xml");
    
            //获取Bean
            UserService userService = context.getBean("userService", UserService.class);
            
            //调用保存用户方法
            userService.saveUser();
    
        }
    }
               
  • 结果
    Spring DI(依赖注入)之xml配置

总结

​ 以上就是Spring的xml配置依赖注入的方式,在xml配置的时候一步一步来,看清楚一个类中依赖了哪些类,然后进行各个类的配置。