IOC目录

基于XML配置方式组件管理

1. 组件(Bean)信息声明配置(IoC)

2. 组件(Bean)依赖注入配置(DI)

3. IoC容器创建和使用

4. 组件(Bean)周期方法和作用域配置

4.1 组件周期方法配置

4.2 组件作用域配置

5. 基于XML方式整合三层架构组件

IOC前言

IoC/DI概念

IoC容器

IoC 容器,负责实例化、配置和组装 bean(组件)核心容器。容器通过读取配置元数据来获取有关实例化、配置和组装组件的指令。

IoC( of )控制反转

IoC 主要是针对对象的创建和调用控制而言的,也就是说,当应用程序需要使用一个对象时,不再是应用程序直接创建该对象,而是由 IoC 容器来创建和管理,即控制权由应用程序转移到 IoC 容器中,也就是“反转”了控制权。

这种方式基本上是通过依赖查找的方式来实现的,即 IoC 容器维护着构成应用程序的对象,并负责创建这些对象。

DI ( ) 依赖注入

DI 是指在组件之间传递依赖关系的过程中,将依赖关系在容器内部进行处理,这样就不必在应用程序代码中硬编码对象之间的依赖关系,实现了对象之间的解耦合。

在 中,DI 是通过 XML 配置文件或注解的方式实现的。它提供了三种形式的依赖注入:构造函数注入、 方法注入和接口注入。

基于XML配置方式组件管理1. 组件(Bean)信息声明配置(IoC)

通过定义XML配置文件,声明组件类信息,交给 的 IoC 容器进行组件管理。

IoC 容器管理一个或多个 bean,这些 bean 的作用是提供给容器的配置元数据创建的(例如,以 XML 定义的形式)。

直流电机正反转控制_ioc控制反转_反转控制电路图

导入相关依赖

<dependencies>
    
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>6.0.6</version>
    </dependency>
    
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.3.1</version>
    </dependency>
</dependencies>

1、基于无参数构造函数

当通过构造函数方法创建一个 bean(组件对象) 时,所有普通类都可以由 使用并与之兼容。在默认情况下,我们需要一个默认(空)构造函数。

①组件类(.java)

package com.xiaof.ioc_01;

public class HappyComponent {
    //默认包含无参数构造函数
    public void doWork() {
        System.out.println("HappyComponent.doWork");
    }
}

②xml配置文件编写 (创建携带约束的xml配置文件)

反转控制电路图_ioc控制反转_直流电机正反转控制

编写xml配置文件(-bean-01.xml)

标签:通过配置bean标签告诉IOC容器需要创建对象的组件信息



<bean id="happyComponent1" class="com.xiaof.ioc_01.HappyComponent"/>
<bean id="happyComponent2" class="com.xiaof.ioc_01.HappyComponent"/>

2、基于静态工厂方法实例化

①组件类(.java)

package com.xiaof.ioc_01;

public class ClientService {
    private static ClientService clientService = new ClientService();
    
    private ClientService() {}
    public static ClientService createInstance() // 静态方法
        return clientService;
    }
}

②xml配置文件(-bean-01.xml)

-: 指定静态工厂方法(该方法必须是方法)


<bean id="clientService" 
      class="com.xiaof.ioc_01.ClientService" 
      factorymethod="createInstance"/>

3、基于实例工厂方法实例化(非静态)

①组件类(.java)

package com.xiaof.ioc_01;

public class ClientServiceImpl {
}

r.java

package com.xiaof.ioc_01;

public class DefaultServiceLocator {
    private static ClientServiceImpl clientService = new ClientServiceImpl();
    public ClientServiceImpl createClientServiceInstance() {
        return clientService;
    }
}

②xml配置文件(-bean-01.xml)

-bean属性:指定当前容器中工厂Bean 的名称



<bean id="defaultServiceLocator"  
      class="com.xiaof.ioc_01.DefaultServiceLocator"/>


<bean id="clientService2" 
      factory-bean="defaultServiceLocator" 
      factory-method="createClientServiceInstance"/>

图解IoC配置流程

反转控制电路图_直流电机正反转控制_ioc控制反转

2. 组件(Bean)依赖注入配置(DI)

通过配置文件,实现IoC容器中Bean之间的引用(依赖注入DI配置)。

主要涉及注入场景:基于构造函数的依赖注入和基于 的依赖注入。

直流电机正反转控制_反转控制电路图_ioc控制反转

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

基于构造函数的 DI 是通过容器调用具有多个参数的构造函数来完成的,每个参数表示一个依赖项。

①组件类(.java)

package com.xiaof.ioc_02;

public class UserDao {
}

.java

package com.xiaof.ioc_02;

public class UserService {
    private UserDao userDao;

    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
}

②xml配置文件(-02.xml)

:指定构造参数和对应的值



<bean id="userDao" class="com.xiaof.ioc_02.UserDao"/>

<bean id="userService" class="com.xiaof.ioc_02.UserService">
    
    <constructor-arg ref="userDao"/>
</bean>

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

①组件类(.java)

package com.xiaof.ioc_02;

public class UserService {
    private UserDao userDao;
    private int age;
    private String name;

    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
    public UserService(int age , String name ,UserDao userDao) {
        this.age = age;
        this.name = name;
        this.userDao = userDao;
    }
}

②xml配置文件(-02.xml)

:指定构造参数和对应的值


<bean id="userService1" class="com.xiaof.ioc_02.UserService">
    
    <constructor-arg value="18"/>
    <constructor-arg value="张三"/>
    <constructor-arg ref="userDao"/>
</bean>
 
<bean id="userService2" class="com.xiaof.ioc_02.UserService">
    <constructor-arg index="1" value="张三"/>
    <constructor-arg index="0" value="18"/>
    <constructor-arg index="2" ref="userDao"/>
</bean>
 
<bean id="userService3" class="com.xiaof.ioc_02.UserService">
    <constructor-arg name="age" value="18"/>
    <constructor-arg name="name" value="张三"/>
    <constructor-arg name="userDao" ref="userDao"/>
</bean>

3、基于方法依赖注入

①组件类(.java)

package com.xiaof.ioc_02;

public class MovieFinder {
}

.java

package com.xiaof.ioc_02;

public class SimpleMovieLister {
    private MovieFinder movieFinder;
    private String movieName;

    public void setMovieFinder(MovieFinder movieFinder) // setter方法
        this.movieFinder = movieFinder;
    }
    public void setMovieName(String movieName){
        this.movieName = movieName;
    }
}

②xml配置文件(-02.xml)

:给方法对应的属性赋值


<bean id="movieFinder" class="com.xiaof.ioc_02.MovieFinder"/>
<bean id="simpleMovieLister" class="com.xiaof.ioc_02.SimpleMovieLister">
    
    <property name="movieFinder" ref="movieFinder"/>
    <property name="movieName" value="霸王别姬"/>
</bean>

3. IoC容器创建和使用

将配置文件中声明组件类信息进行实例化成Bean对象和形成Bean之间的引用关系,需要声明IoC容器对象,读取配置文件ioc控制反转,实例化组件和关系维护的过程都是在IoC容器中实现的。

在test目录下新建一个测试类.java

1、容器实例化

new (...)

public class SpringIoCTest {
    /**
     * 创建IOC容器并读取配置文件
     *      接口:BeanFactory、ApplicationContext
     *      实现类:可以直接通过构造函数实例化
     *      ClassPathXmlApplicationContext[推荐]
     *      FileSystemXmlApplicationContext
     *      AnnotationConfigApplicationContext
     *      WebApplicationContext
     */

    @Test
    public void createIoC(){
        // 方式1:实例化并指定配置文件
        // 参数:String...locations:传入一个或者多个配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-01.xml","spring-03.xml");

        // 方式2:先实例化,再指定配置文件,最后刷新容器触发Bean实例化动作(springmvc源码和contextLoadListener源码方式]
        // 参数:String...locations:传入一个或者多个配置文件
        ClassPathXmlApplicationContext applicationContext1 = new ClassPathXmlApplicationContext();
        applicationContext1.setConfigLocation("spring-03.xml"); // 设置配置文件
        applicationContext1.refresh(); // 触发刷新配置
    }
}

2、Bean对象读取

❝包

组件类

package com.xiaof.ioc_03;

public class HappyComponent implements A{
//默认包含无参数构造函数

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

接口A

package com.xiaof.ioc_03;

public interface A {
void doWork();
}

xml配置文件(-03.xml)

<bean id="happyComponent" class="com.xiaof.ioc_03.HappyComponent"/>

public class SpringIoCTest {
 /**
     * 在IOC容器中获取组件Bean
     */

   @Test
   public void getBeanFromIoC(){
       // 创建ioc容器对象
       ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
       applicationContext.setConfigLocation("spring-03.xml");
       applicationContext.refresh();

       // 读取ioc容器的组件
       // 方案1:直接根据beanId读取即可,返回值类型是Object,需要强转[不推荐]
       HappyComponent happyComponent = (HappyComponent) applicationContext.getBean("happyComponent");
       // 方案2:根据beanId,同时指定bean的类型Class
       HappyComponent happyComponent1 = applicationContext.getBean("happyComponent",HappyComponent.class);
       // 方案3:直接根据类型获取
       // TODO:根据bean的类型获取,同一个类型,在ioc容器中只能用一个bean!
       // HappyComponent happyComponent2 = applicationContext.getBean(HappyComponent.class);
       // TODO:ioc的配置一定是实现类,但可以根据接口类型获取值 getBean(类型) instanceof ioc容器的类型 == true
       A happyComponent2 = applicationContext.getBean(A.class);

       happyComponent.doWork();
       System.out.println(happyComponent == happyComponent1);
       System.out.println(happyComponent1 == happyComponent2);
   }
}

3、返回结果

ioc控制反转_直流电机正反转控制_反转控制电路图

4. 组件(Bean)周期方法和作用域配置

4.1 组件周期方法配置

在组件类中定义方法,当IoC容器实例化和销毁组件对象的时候进行调用ioc控制反转,这两个方法称为生命周期方法。类似于的init/方法,可以在周期方法完成初始化和释放资源等工作。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注