Spring Learning Note——IOC

IOC(Inversion of Control)?

将设计好的对象移交给容器控制;反转:原来是通过new关键字主动获取依赖的对象,而IOC有专门的容器负责控制(创建、初始化、销毁)。
IoC 具体实现:依赖注入(DI(Dependency Injection)——组件之间的依赖关系有容器在运行时期决定,容器动态的将某一个依赖关系注入到组件之中)
【通俗理解一下,就是设计好了一批组件(类),他们之间可能互相会存在一定的组合依赖关系,比如其中一个类的成员是另一个类的引用,此时将这一批类注册(就是登记一下,声明类的具体位置,如何识别等等)到IOC容器,IOC容器会在运行程序的时候动态的将需要的对象注入相关的组件】

为什么使用?

  • 实现组件之间解耦
  • 提高程序的灵活性、可维护性、可拓展性
  • 提升组件重用率

例子

1. 创建一个Maven Project工程,archetype选择quickstart:

创建Maven工程

2. 配置pom.xml:

在properties中添加Spring版本号

<spring.version>5.0.0.RELEASE</spring.version>

引入依赖

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

3. 定义一个接口:

package ioctest;

/**
 * @author 舟吉
 * @create 2020-12-22
 */
public interface IAir {
}

4. 以下两个实现类实现接口:

package ioctest;

import org.springframework.stereotype.Component;

/**
 * @author 舟吉
 * @create 2020-12-22
 */
@Component
public class CleanAir implements IAir{

    @Override
    public String toString() {
//        return super.toString();
        return "CleanAir";
    }
}
package ioctest;

import org.springframework.stereotype.Component;

/**
 * @author 舟吉
 * @create 2020-12-22
 */
@Component
public class DirtyAir implements IAir {

    @Override
    public String toString() {
//        return super.toString();
        return "DirtyAir";
    }
}

5. 使用前面的类

package ioctest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * @author 舟吉
 * @create 2020-12-22
 */
@Component
public class ErHa {

    /*
    *此处没有new一个CleanAir对象而是使用@Qualifier标记
    *由IoC容器后面在运行时识别标识为cleanair的组件或者类并赋给这个构造器(依赖注入)
    */
    @Autowired
    public ErHa(@Qualifier("cleanair") IAir air){
        this.air = air;
    }

    IAir air;//作为erha(二哈)的成员变量——>依赖

    public void Breath(){
        System.out.println(this.air.toString());
    }
}

6. 在scr/main/resources下面新建一个ApplicationContext.xml(没有resources则新建一个对应的目录即可)

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置组件 -->
    <context:component-scan base-package="ioctest"/>
    <bean id="CleanAir" class="ioctest.CleanAir">
        <qualifier value="cleanair"></qualifier>
    </bean>
    <bean id="DirtyAir" class="ioctest.DirtyAir">
        <qualifier value="dirtyAir"></qualifier>
    </bean>
    <bean id="erha" class="ioctest.ErHa"></bean>

</beans>

记录一个问题

#问题:expected single matching bean but found 2: cleanAir,CleanAir

@Component
public class ErHa {

    @Autowired
    public ErHa(@Qualifier("cleanAir") IAir air){//此处声明的Qualifier为cleanAir
        this.air = air;
    }

    IAir air;

    public void Breath(){
          ...
    }    
}

相关的配置文件声明如下,但是会出现之前的报错:
expected single matching bean but found 2: cleanAir,CleanAir

<bean id="CleanAir" class="ioctest.CleanAir">
        <qualifier value="cleanAir"></qualifier>
</bean>

如果修改配置文件中的qualifier value为cleanair则正常运行
(此时无论是CleanAir还是cleanair都和注解所声明的cleanAir不相匹配)

<bean id="CleanAir" class="ioctest.CleanAir">
        <qualifier value="cleanair"></qualifier>
</bean>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容