IoC利用xml进行配置文件以及依赖注入

89 阅读3分钟

实验一:组件(Bean)信息声明配置(IoC)

(无参、静态、非静态三种配置方法)

1. 准备项目

    1. 创建maven工程(spring-ioc-xml-01)
    2. 导入SpringIoC相关依赖 pom.xml
<dependencies>
  <!--spring context依赖-->
  <!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了-->
  <dependency>
    <groupId>org.springframework</groupId>

    <artifactId>spring-context</artifactId>

    <version>6.0.6</version>

  </dependency>

  <!--junit5测试-->
  <dependency>
    <groupId>org.junit.jupiter</groupId>

    <artifactId>junit-jupiter-api</artifactId>

    <version>5.3.1</version>

  </dependency>

</dependencies>

创建spring的xml配置文件

2. 基于无参数构造函数

当通过构造函数方法创建一个 bean(组件对象) 时,所有普通类都可以由 Spring 使用并与之兼容。也就是说,正在开发的类不需要实现任何特定的接口或以特定的方式进行编码。只需指定 Bean 类信息就足够了。但是,默认情况下,我们需要一个默认(空)构造函数。

  1. 准备组件类,放在java中
package com.atguigu.ioc;

public class HappyComponent {

    //默认包含无参数构造函数

    public void doWork() {
        System.out.println("HappyComponent.doWork");
    }
}

2. xml配置文件编写 文件:resources/spring-bean-01.xml

<?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">

    <!-- 1.可以使用无参数构造函数实例化的逐渐,如何进行ioc配置
        一个bean就是一个组件信息和逐渐对象
           id 组件的标识要 唯一 方便后期读取
           class 逐渐的类的权限定符
           每次声明默认都是单例模式(每次都会实例化一次对象)下面那种就是实例化了两个
    -->
  <bean id="happyComponent1" class="com.atguigu.ioc_01.HappyComponent"/>
  <bean id="happyComponent2" class="com.atguigu.ioc_01.HappyComponent"/>
</beans>

3. 基于静态工厂方法实例化

  1. 准备组件类
public class ClientService {
    private static ClientService clientService = new ClientService();
    private ClientService() {}

    public static ClientService createInstance() {

        return clientService;
    }
}

2. xml配置文件编写 文件:resources/spring-bean-01.xml

<?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">
    
    <!-- 2.使用静态工厂类如何声明工厂方法进行ioc的配置
               id 组件的标识
               class 逐渐的类的权限定符
               factory-method = "静态工厂方法"
               每次声明默认都是单例模式(每次都会实例化一次对象)
        -->
    <bean id="clientService" class="com.atguigu.ioc_01.ClientService" 
      factory-method="createInstance"/>
</beans>

4. 基于实例工厂方法实例化

  1. 准备组建类
public class DefaultServiceLocator {

    private static ClientServiceImplclientService = new ClientServiceImpl();

    public ClientService createClientServiceInstance() {
        return clientService;
    }
}

2. xml配置文件编写 文件:resources/spring-bean-01.xml

<?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">
    
    <!-- 3.使用非静态工厂类如何声明工厂方法进行ioc的配置-->
    <!-- 3.1 配置工厂类的组件信息 -->
    <bean id="defaultServiceLocator" class="com.atguigu.ioc_01.DefaultServiceLocator"/>
    <!-- 3.2 通过指定非静态工厂对象和方法名 来配置生成的ioc信息
              factory-bean 指定的非静态工厂
              factory-method 指定的非静态工厂的函数方法 -->
    <bean id="clientService2" 
      factory-bean="defaultServiceLocator" 
      factory-method="createClientServiceInstance"/> 
  
</beans>

实验二: 组件(Bean)依赖注入配置(DI)

<constructor-arg ref="userDao"/> <!-- 注入的参数是一个引用其他bean的 引用beanid值-->
<constructor-arg  value="18"/>   <!-- 注入的参数是一个直接的数值-->

1. 基于构造函数的依赖注入(单个构造参数)

 <beans>
        <!-- 单个构造参数的注入 -->
        <!-- 引用类bean声明 -->
        <bean id="userService" class="com.atguigu.ioc_02.UserService">
            <!-- 构造函数引用 -->
            <constructor-arg ref="userDao"/>
        </bean>
        <!-- 被引用类bean声明 (声明的顺序不重要)-->
        <bean id="userDao" class="com.atguigu.ioc_02.UserDao"/>
    </beans

2.基于构造函数的依赖注入(多构造参数解析)

<!-- 多个构造参数的注入 -->
    <!-- 场景1: 多参数,可以按照相应构造函数的顺序注入数据 -->
    <beans>
        <bean id="userService" class="com.atguigu.ioc_02.UserService">
            <!-- value直接注入基本类型值 -->
            <constructor-arg  value="18"/>
            <constructor-arg  value="赵伟风"/>
            <constructor-arg  ref="userDao"/>
        </bean>
        <!-- 被引用类bean声明 -->
        <bean id="userDao" class="com.atguigu.ioc_02.UserDao"/>
    </beans>

    <!-- 场景2: 多参数,可以按照相应构造函数的名称注入数据 -->
    <beans>
        <bean id="userService" class="com.atguigu.ioc_02.UserService">
            <!-- value直接注入基本类型值 -->
            <constructor-arg name="name" value="赵伟风"/>
            <constructor-arg name="userDao" ref="userDao"/>
            <constructor-arg name="age"  value="18"/>
        </bean>
        <!-- 被引用类bean声明 -->
        <bean id="userDao" class="com.atguigu.ioc_02.UserDao"/>
    </beans>

    <!-- 场景3: 多参数,可以按照相应构造函数的角标注入数据
               index从0开始 构造函数(0,1,2....)
    -->
    <beans>
        <bean id="userService" class="com.atguigu.ioc_02.UserService">
            <!-- value直接注入基本类型值 -->
            <constructor-arg index="1" value="赵伟风"/>
            <constructor-arg index="2" ref="userDao"/>
            <constructor-arg index="0"  value="18"/>
        </bean>
        <!-- 被引用类bean声明 -->
        <bean id="userDao" class="com.atguigu.ioc_02.UserDao"/>
    </beans>

3. 基于Setter方法依赖注入 (重点)

public Class MovieFinder{

}

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    private String movieName;

    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    public void setMovieName(String movieName){
        this.movieName = movieName;
    }

    // business logic that actually uses the injected MovieFinder is omitted...
}
<beans>
        <bean id="movieFinder" class="com.atguigu.ioc_02.MovieFinder"/>
        <bean id="simpleMovieLister" class="com.atguigu.ioc_02.SimpleMovieLister">
            <!-- (必填)name -> 属性名 调用set方法的名字 去掉set并首字母小写的值!
                setMovieFinder -> movieFinder
                 (二选一) value | ref
            -->
            <property name="movieName" value="hello world"/>
            <property name="movieFinder" ref="movieFinder"/>
        </bean>
    </beans>