Spring - 控制反转IOC

1. IOC思想

IOC: Inversion of Control,即控制反转的意思。
传统方式: 主动从容器中获取所需资源。比如需要一个对象实例时候,需要手动去new一个。
控制反转:只需要说明需要什么资源即可。
DI:Dependency Injection,翻译过来是依赖注入。
以一些预先定义好的方式(例如:setter 方法, 构造函数)接受来自于容器的资源注入。相对于IOC而言,这种表述更直接。也就是说,使用的时候不需要自己手动去new。
IOC 就是一种反转控制的思想, 而 DI 是对 IOC 的一种具体实现。IOC创建对象,DI来给创建出来的对象属性赋值。

2. IOC 在Spring中的实现

Ctrl + H查看当前接口子类以及继承关系。

  1. BeanFactory
    这是 IOC 容器的基本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用。
  2. ApplicationContext
    BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用
    ApplicationContext 而不是底层的 BeanFactory。
  3. ApplicationContext的主要实现类
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    类型名 简介
    ClassPathXmlApplicationContext 通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象
    FileSystemXmlApplicationContext 通过文件系统路径读取 XML 格式的配置文件创建 IOC 容器对象
    ConfigurableApplicationContext
    ApplicationContext 的子接口,包含一些扩展方法refresh() 和 close() ,让 ApplicationContext 具有启动、关闭和刷新上下文的能力。
    WebApplicationContext 专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对象,并将对象引入存入 ServletContext 域中。

3、IOC创建对象方法

测试步骤
step1: 创建Module;
step2:pom中引入依赖

 <packaging>jar</packaging>

    <dependencies>
        <!-- 基于Maven依赖传递性,导入spring-context依赖即可导入当前所需所有jar包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.1</version>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

step3: 项目中创建一个bean

package com.lucky.spring.bean;

public class HelloWorld {

    public void sayHello() {
        System.out.println("hello lucky");
    }
}

step4:创建spring配置文件
在这里插入图片描述xml文件中配置bean

<?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">
    <!--
        配置HelloWorld所对应的bean,即将HelloWorld的对象交给Spring的IOC容器管理
        通过bean标签配置IOC容器所管理的bean
        属性:
        id:设置bean的唯一标识
        class:设置bean所对应类型的全类名
     -->
    <bean id="helloWord" class="com.lucky.spring.bean.HelloWorld"></bean>
    <bean id="helloWord1" class="com.lucky.spring.bean.HelloWorld"></bean>
</beans>

step5: 构建测试类进行测试

 @Test
    public void helloTest() {

        // ClassPathXmlApplicationContext 从工程目录获取资源
        // 可以使用applicationContext.xml作为路径,是因为打包之后,resource路径下的文件和java文件下都被打包到了类路径
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 1、通过配置文件中id获取bean
        HelloWorld helloWorld = (HelloWorld) ac.getBean("helloWord");
    }

通过反射的方法,调用无参构造,删除无参构造,报错。

4、获取bean的三种方式

1、根据bean的id

 // ApplicationContext 是一个接口,new一个该接口的实现类,来使用,这个接口还有一个实现类,是从磁盘目录来加载资源的
// ClassPathXmlApplicationContext 从工程目录获取资源
// 可以使用applicationContext.xml作为路径,是因为打包之后,resource路径下的文件和java文件下都被打包到了类路径
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 1、通过配置文件中id获取bean
HelloWorld helloWorld = (HelloWorld) ac.getBean("helloWord");

2、根据bean类型

HelloWorld helloWorld1 = ac.getBean(HelloWorld.class);

如果xml里面配置了两个不同id,针对同一个类型HelloWorld.class,如下:

<bean id="helloWord" class="com.lucky.spring.bean.HelloWorld"></bean>
<bean id="helloWord1" class="com.lucky.spring.bean.HelloWorld"></bean>

会报错,找到了两个,不唯一
在这里插入图片描述配置文件不配置也会报错找不到
在这里插入图片描述

因此当根据类型获取bean时,要求IOC容器中指定类型的bean有且只能有一个。这种方法用的比较多,因为之后每种类型的bean一般情况下只配置一个id。

3. 通过类型和id一起获取
这个时候xml文件同一类型配置两个不同id也是可行的。
注意:
1、如果组件类实现了接口,根据接口类型可以获取 bean 吗?
可以,前提是bean唯一
2、如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口类型可以获取 bean 吗?
不行,因为bean不唯一
根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:『对象 instanceof 指定的类
型』的返回结果,只要返回的是true就可以认定为和类型匹配,能够获取到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值