目录
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。
-