2025/2/25 下午《尚硅谷》——Spring IOC 容器中获取 Bean 的几种方式及其注意事项

目录

一、根据 Bean 的 ID 获取

1. spring-ioc.xml 配置

2. 测试代码

3. 解析

二、根据 Bean 的类型获取

1. 注意事项

2. 示例一:存在多个同类型 Bean

spring-ioc.xml 配置

测试代码

输出结果

分析

3. 示例二:没有匹配的 Bean

spring-ioc.xml 配置

测试代码

输出结果

分析

三、根据 Bean 的 ID 和类型获取

1. spring-ioc.xml 配置

2. 测试代码

3. 输出结果

4. 解析

四、扩展

1. 如果组件类实现了接口,根据接口类型可以获取 Bean 吗?

2. 如果一个接口有多个实现类,这些实现类都配置了 Bean,根据接口类型可以获取 Bean 吗?

五、结论


spring-ioc.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">

    <bean id="studentOne" class="com.atguigu.spring.pojo.Student"></bean>

</beans>

IOCByXMLTest.Java代码

package com.atguigu.spring.test;

import com.atguigu.spring.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class IOCByXMLTest {

    @Test
    public void testIOC(){
        //获取IOC容器
        ApplicationContext  ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
        //获取bean
        Student studentOne = (Student) ioc.getBean("studentOne");
        System.out.println(studentOne);
    }

}

一、根据 Bean 的 ID 获取

1. spring-ioc.xml 配置
<bean id="studentOne" class="com.atguigu.spring.pojo.Student"></bean>
2. 测试代码
Student studentOne = (Student) ioc.getBean("studentOne");
System.out.println(studentOne);
3. 解析
  • ioc.getBean("studentOne"):通过 Bean 的 ID(studentOne)从 IOC 容器中获取对应的 Bean。

  • 输出结果

Student{sid=null, sname='null', age=null, gender='null'}
    • 由于没有为 Student Bean 设置属性值,因此输出的属性值均为 null


二、根据 Bean 的类型获取

1. 注意事项
  • 根据类型获取 Bean 时,要求 IOC 容器中有且只有一个类型匹配的 Bean。

  • 如果存在多个同类型的 Bean,Spring 会抛出 NoUniqueBeanDefinitionException 异常。

  • 如果没有匹配的 Bean,Spring 会抛出 NoSuchBeanDefinitionException 异常。

2. 示例一:存在多个同类型 Bean
spring-ioc.xml 配置
<bean id="studentOne" class="com.atguigu.spring.pojo.Student"></bean>
<bean id="studentTwo" class="com.atguigu.spring.pojo.Student"></bean>
测试代码
Student student = ioc.getBean(Student.class);
System.out.println(student);
输出结果
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.atguigu.spring.pojo.Student' available: expected single matching bean but found 2: studentOne,studentTwo
分析
  • 容器中存在两个 Student 类型的 Bean(studentOne 和 studentTwo),Spring 无法确定返回哪一个,因此抛出异常。

3. 示例二:没有匹配的 Bean
spring-ioc.xml 配置
<!-- 没有定义任何 Bean -->
测试代码
Student student = ioc.getBean(Student.class);
System.out.println(student);
输出结果
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.atguigu.spring.pojo.Student' available
分析
  • 容器中没有定义 Student 类型的 Bean,因此抛出异常。


三、根据 Bean 的 ID 和类型获取

1. spring-ioc.xml 配置
<bean id="studentOne" class="com.atguigu.spring.pojo.Student"></bean>
<bean id="studentTwo" class="com.atguigu.spring.pojo.Student"></bean>
2. 测试代码
Student student = ioc.getBean("studentOne", Student.class);
System.out.println(student);
3. 输出结果
Student{sid=null, sname='null', age=null, gender='null'}
4. 解析
  • ioc.getBean("studentOne", Student.class):通过 Bean 的 ID(studentOne)和类型(Student.class)从 IOC 容器中获取 Bean。

  • 这种方式可以避免类型不唯一的问题,因为明确指定了 Bean 的 ID。


四、扩展

1. 如果组件类实现了接口,根据接口类型可以获取 Bean 吗?
  • 可以,但前提是 Bean 唯一。

  • 例如:

public interface Person {}
public class Student implements Person {}

// 配置
<bean id="studentOne" class="com.atguigu.spring.pojo.Student"></bean>

// 获取
Person person = ioc.getBean(Person.class);
2. 如果一个接口有多个实现类,这些实现类都配置了 Bean,根据接口类型可以获取 Bean 吗?
  • 不行,因为 Bean 不唯一。

  • 例如:

public interface Person {}
public class Student implements Person {}
public class Teacher implements Person {}

// 配置
<bean id="studentOne" class="com.atguigu.spring.pojo.Student"></bean>
<bean id="teacherOne" class="com.atguigu.spring.pojo.Teacher"></bean>

// 获取
Person person = ioc.getBean(Person.class); // 抛出 NoUniqueBeanDefinitionException

五、结论

  • 根据类型获取 Bean 时

    • 在满足 Bean 唯一性的前提下,Spring 会检查 对象 instanceof 指定的类型,如果返回 true,则认为类型匹配,可以获取到 Bean。

    • 如果存在多个同类型的 Bean,Spring 会抛出 NoUniqueBeanDefinitionException

    • 如果没有匹配的 Bean,Spring 会抛出 NoSuchBeanDefinitionException

    • Unique——翻译为:唯一的。

  • 根据 ID 和类型获取 Bean 时

    • 可以避免类型不唯一的问题,因为明确指定了 Bean 的 ID。