Spring - Spring IoC 容器相关面试题总结

news2025/7/19 7:15:39

文章目录

      • 01. Spring IoC 和依赖注入是什么?
      • 02. Spring IoC 的优点和缺点分别是什么?
      • 03. Spring IoC 有什么作用和功能?
      • 04. Spring 依赖注入的方式?
      • 05. Spring 构造器注入和 setter 方法注入的区别?
      • 06. Spring 依赖注入的基本原则?
      • 07. Spring 依赖注入有什么优势?
      • 08. Spring 的配置方式有几种?
      • 09. Spring IoC 的实现机制?
      • 10. 什么是 Spring IoC 容器?
      • 11. Spring 中有几种 IoC 容器?
      • 13. Spring ApplicationContext 通常的实现是什么?
      • 12. Spring BeanFactory 和 ApplicationContext有什么区别?
      • 14. Spring 容器是如何设计的?
      • 15. Spring 容器如何配置元数据?
      • 16. Spring BeanFactory 容器如何使用?
      • 17. Spring ApplicationContext 容器如何使用?
      • 18. Spring BeanFactory 容器源码?
      • 19. Spring ApplicationContext 源码?

01. Spring IoC 和依赖注入是什么?

Spring IoC(Inversion of Control,控制反转)是一种设计模式,它通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度,提高了代码的可维护性和可测试性。

控制反转:依赖对象的获取方式被反转了,从主动创建依赖对象,变成由容器创建并注入依赖对象。
依赖注入:组件之间依赖关系由容器在运行期决定的,即由容器动态地将某个依赖关系注入到组件之中。

如果我们依赖于某个类或服务,最简单而有效的方式就是直接在类的构造函数中新建相应的依赖类,自己主动地去获取依赖的对象!可是回头想想,我们自己每次用到什么依赖对象都要主动地去获取,这是否真的必要?我们最终所要做的,其实就是直接调用依赖对象所提供的某项服务而已。只要用到这个依赖对象的时候,它能够准备就绪,我们完全可以不管这个对象是自己找来的还是别人送过来的。

public class FXNewsProvider {
// FXNewsProvider 需要依赖 IFXNewsListener
private IFXNewsListener newsListener;

// 需要在构造函数中构造 IFXNewsProvider 依赖的类
public FXNewsProvider(){
newsListener = new DowJonesNewsListener();
}
}

IOC 它的反转,就反转在让你从原来的事必躬亲,转变为现在的享受服务,让别人为你服务!也就是让 IOC 容器来为你服务!

通常情况下,被注入对象会直接依赖于被依赖对象,二者之间通过IOC容器打交道,所有的被注入对象和依赖对象现在由IOC容器统一管理。被注入对象需要什么,直接跟IOC容器招呼一声,后者就会把相应的被依赖对象注入到被注入对象中,从而达到IOC容器为被注入对象服务的目的。

从被注入对象的角度看,与之前自己主动获取依赖对象相比,依赖对象的获取方式发生了反转,控制也从被注入对象转到了IOC容器那里。

02. Spring IoC 的优点和缺点分别是什么?

Spring IoC 的优点:

① 降低组件之间的耦合度:Spring IOC 容器负责管理 Bean 对象及其依赖关系,使得组件之间的耦合度降低,从而提高了代码的可维护性和可测试性。

② 提高代码的可重用性:通过将 Bean 对象的创建和依赖关系的管理交给容器来实现,可以使得代码更加模块化和可重用。

③ 简化配置和管理:Spring IOC 容器可以通过配置文件或注解来管理 Bean 对象及其依赖关系,从而简化了配置和管理的工作。

④ 支持 AOP:Spring IOC 容器提供了 AOP 支持,可以通过配置元数据或注解来定义切面和通知,从而实现对 Bean 的增强。

⑤ 提高系统的可扩展性:通过使用 Spring IOC 容器,可以将系统的各个组件解耦,从而提高了系统的可扩展性和灵活性。

Spring IoC 的缺点:

① 学习成本较高:Spring IOC 框架是一个比较庞大的框架,需要花费一定的时间和精力来学习和掌握。

② 运行时性能较低:由于 Spring IOC 容器需要在运行时动态地创建和管理 Bean 对象,因此会对系统的性能产生一定的影响。

③ 配置文件较为复杂:Spring IOC 容器的配置文件比较复杂,需要编写大量的 XML 或注解代码来定义 Bean 对象及其依赖关系。

④ 容器的管理和维护较为复杂:由于 Spring IOC 容器负责管理系统中的所有 Bean 对象,因此容器的管理和维护较为复杂,需要花费一定的时间和精力来维护。

总的来说,Spring IOC 的优点远远大于缺点,它可以帮助开发者实现松耦合的设计,提高代码的可维护性和可测试性,从而提高了系统的可扩展性和灵活性。

03. Spring IoC 有什么作用和功能?

Spring IoC 是 Spring 框架的核心机制之一,它的作用和功能主要包括以下几个方面:

① 管理 Bean 对象:Spring IOC 容器负责创建和管理 Bean 对象,可以通过配置文件或注解来定义 Bean 对象及其依赖关系。

② 降低组件之间的耦合度:Spring IOC 容器负责管理 Bean 对象及其依赖关系,使得组件之间的耦合度降低,从而提高了代码的可维护性和可测试性。

③ 提高代码的可重用性:通过将 Bean 对象的创建和依赖关系的管理交给容器来实现,可以使得代码更加模块化和可重用。

④ 简化配置和管理:Spring IOC 容器可以通过配置文件或注解来管理 Bean 对象及其依赖关系,从而简化了配置和管理的工作。

⑤ 支持 AOP:Spring IOC 容器提供了 AOP 支持,可以通过配置元数据或注解来定义切面和通知,从而实现对 Bean 的增强。

⑥ 提高系统的可扩展性:通过使用 Spring IOC 容器,可以将系统的各个组件解耦,从而提高了系统的可扩展性和灵活性。

总的来说,Spring IOC 的作用和功能是管理 Bean 对象及其依赖关系,降低组件之间的耦合度,提高代码的可重用性和可维护性,简化配置和管理,支持 AOP,提高系统的可扩展性和灵活性。

04. Spring 依赖注入的方式?

被注入对象可以通过2种方式来通知 IOC容器为其提供服务:构造方法注入、setter方法注入。

① 构造方法注入:

被注入对象可以通过在其构造方法中声明依赖对象的参数列表,让 IOC 容器知道它需要哪些依赖对象。IOC 容器会检查被注入对象的构造方法,取得它所需要的依赖对象列表,进而为其注入相应的对象。构造方法注入方式比较直观,对象被构造完成后,即进入就绪状态,可以马上使用。

② setter方法注入:

对于JavaBean对象来说,通常会通过setXXX()和getXXX()方法来访问对应属性。这些setXXX()方法统称为setter方法,通过setter方法,可以更改相应的对象属性,所以,当前对象只要为其依赖对象所对应的属性添加setter方法,就可以通过setter方法将相应的依赖对象设置到被注入对象中。setter方法注入虽不像构造方法注入那样,让对象构造完成后即可使用,但相对来说更宽松一些,可以在对象构造完成后再注入。

05. Spring 构造器注入和 setter 方法注入的区别?

具体代码实例可以看我的另一篇文章:SpringBoot - Bean的实例化和依赖注入方式

① 构造方法注入:

构造器注入是指通过构造器来注入 Bean 的依赖关系,它要求 Bean 的依赖关系在创建 Bean 实例时就已经确定,因此可以保证 Bean 的不可变性和线程安全性。构造器注入的缺点是需要编写更多的代码,而且对于复杂的依赖关系,构造器注入可能会变得很复杂。

当依赖对象比较多的时候,构造方法的参数列表会比较长。而通过反射构造对象的时候,对相同类型的参数的处理会比较困难,维护和使用上也比较麻烦。而且在Java中,构造方法无法被继承,无法设置默认值。对于非必须的依赖处理,可能需要引入多个构造方法,而参数数量的变动可能造成维护上的不便。

② setter方法注入:

setter 方法注入是指通过 setter 方法来注入 Bean 的依赖关系,它允许 Bean 的依赖关系在运行时动态地改变,因此更加灵活。setter 方法注入的缺点是可能会导致 Bean 的状态不可预测,从而影响程序的可维护性和可测试性。

在实际开发中,通常会根据具体的情况选择使用构造器注入或 setter 方法注入。一般来说,如果 Bean 的依赖关系比较简单,可以使用 setter 方法注入;如果 Bean 的依赖关系比较复杂,或者需要保证 Bean 的不可变性和线程安全性,可以使用构造器注入。

06. Spring 依赖注入的基本原则?

Spring 依赖注入的基本原则是“面向接口编程”和“依赖倒置原则”:

① 面向接口编程是指在编写代码时,应该针对接口编程,而不是针对具体的实现类编程。这样可以使得代码更加灵活和可扩展,从而提高了系统的可维护性和可测试性。

② 依赖倒置原则是指高层模块不应该依赖于低层模块,而是应该依赖于抽象接口。这样可以使得系统的各个组件之间解耦,从而提高了系统的可扩展性和灵活性。

③ 在 Spring 中,依赖注入的基本原则是通过接口来定义 Bean 对象及其依赖关系,从而实现松耦合的设计。Spring 通过反射机制,将 Bean 对象所依赖的其他 Bean 对象注入到它们的属性中,从而实现对象之间的依赖关系。通过依赖注入,开发者可以将对象之间的依赖关系从代码中抽离出来,从而使代码更加清晰、简洁和易于维护。

总的来说,Spring 依赖注入的基本原则是面向接口编程和依赖倒置原则,它可以帮助开发者实现松耦合的设计,提高代码的可维护性和可测试性,从而提高了系统的可扩展性和灵活性。

07. Spring 依赖注入有什么优势?

Spring 依赖注入的优势主要包括以下几个方面:

① 降低组件之间的耦合度:通过依赖注入,可以将对象之间的依赖关系从代码中抽离出来,从而使得组件之间的耦合度降低,提高了代码的可维护性和可测试性。

② 提高代码的可重用性:通过依赖注入,可以将对象之间的依赖关系从代码中抽离出来,使得代码更加模块化和可重用。

③ 简化配置和管理:通过依赖注入,可以将对象之间的依赖关系从代码中抽离出来,从而简化了配置和管理的工作。

④ 支持 AOP:Spring 依赖注入容器提供了 AOP 支持,可以通过配置元数据或注解来定义切面和通知,从而实现对 Bean 的增强。

⑤ 提高系统的可扩展性:通过使用 Spring 依赖注入容器,可以将系统的各个组件解耦,从而提高了系统的可扩展性和灵活性。

⑥ 支持多种依赖注入方式:Spring 依赖注入容器支持多种依赖注入方式,如构造器注入、setter 方法注入、字段注入等,可以根据实际情况选择最合适的方式。

总的来说,Spring 依赖注入的优势是降低组件之间的耦合度,提高代码的可重用性和可维护性,简化配置和管理,支持 AOP,提高系统的可扩展性和灵活性,同时支持多种依赖注入方式,可以根据实际情况选择最合适的方式。

08. Spring 的配置方式有几种?

对于为被注入对象提供依赖注入的 IOC 容器来说,它需要知道自己所管理和掌握的被注入对象和依赖对象之间的对应关系。IOC使用的注册对象管理信息的方式主要有以下3种:

① 基于 XML 的配置方式:通过编写 XML 配置文件来定义 Bean 对象及其依赖关系。这种方式是 Spring 最早的配置方式,也是最常用的配置方式之一。

② 基于注解的配置方式:Spring 在 2.5 版本以后开始支持用注解的方式,通过在 Bean 对象的类或属性上添加注解来定义 Bean 对象及其依赖关系。这种方式可以使得配置更加简洁和易于维护,但是需要使用 JDK 5.0 及以上版本。注解的初衷是简化 xml 配置的,因此不能单独存在,在 Spring 中是默认关闭的。所以需要在 Spring 文件中配置一下才能使用基于注解的装配模式:

<beans>
    <context:annotation-config/>          
</beans>

③ 基于 Java 的配置方式:Spring 3.0 以后,提供了基于java配置的方式,通过编写 Java 代码来定义 Bean 对象及其依赖关系。这种方式可以使得配置更加灵活和可控,但是需要编写大量的 Java 代码。它可以完全替代 xml 的解决方案,不用xml 配置文件作为配置入口。

@Configuration     
public class AppConfig{
    @Bean         
    public MyService myService() {
        return new MyServiceImpl();
    }     
}

总的来说,Spring 的配置方式有基于 XML 的配置方式、基于注解的配置方式和基于 Java 的配置方式,开发者可以根据实际情况选择最合适的配置方式。

09. Spring IoC 的实现机制?

Spring IoC 的实现机制主要包括以下几个方面:

① 配置元数据的加载:Spring IoC 容器通过读取配置文件或注解来获取 Bean 的定义信息,配置元数据可以使用 XML、JavaConfig 或注解等方式进行定义。

② Bean 的实例化:Spring IoC 容器根据配置元数据中的信息,实例化 Bean 对象。Bean 的实例化可以通过构造函数注入、工厂方法注入或者静态工厂方法注入等方式进行。

③ Bean 的依赖注入:Spring IoC 容器通过反射机制,将 Bean 对象所依赖的其他 Bean 对象注入到它们的属性中,从而实现 Bean 之间的依赖关系。

④ 生命周期管理:Spring IoC 容器管理 Bean 的整个生命周期,包括 Bean 的实例化、依赖注入、初始化、销毁等过程。在 Bean 的生命周期中,Spring IoC 容器会调用 Bean 的初始化方法和销毁方法,以便进行一些必要的操作。

⑤ AOP 支持:Spring IoC 容器提供了 AOP 支持,可以通过配置元数据或注解来定义切面和通知,从而实现对 Bean 的增强。

总的来说,Spring IoC 容器通过配置元数据的加载、Bean 的实例化、依赖注入、生命周期管理和 AOP 支持等机制,实现了对 Bean 的管理和控制,从而降低了组件之间的耦合度,提高了代码的可维护性和可测试性。

10. 什么是 Spring IoC 容器?

Spring IOC容器是Spring框架的核心部分之一,它负责管理应用程序中的对象及其依赖关系。

IOC 是一种设计模式,通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度,提高了代码的可维护性和可测试性。在 Spring 中,IOC 容器负责创建和管理 Bean 对象,Bean 是指在Spring 容器中被管理的对象。容器会根据配置文件或注解来创建Bean对象,并将它们注入到需要它们的地方。

IOC 容器可以分为两种类型:BeanFactory 和 ApplicationContext。BeanFactory 是 Spring IOC 容器的基础接口,提供了最基本的 IOC 功能;ApplicationContext 是 BeanFactory 的子接口,提供了更多的功能,如国际化支持、事件传递、AOP 等。

11. Spring 中有几种 IoC 容器?

在 Spring 框架中,主要有两种类型的 IOC 容器:BeanFactory 和 ApplicationContext。

在这里插入图片描述

① BeanFactory 是 Spring IOC 容器的基础接口,提供了最基本的 IOC 功能,它是一个轻量级的容器,延迟加载 Bean,只有在使用时才会创建 Bean 实例。

② ApplicationContext 是 BeanFactory 的子接口,提供了更多的功能,如国际化支持、事件传递、AOP 等。ApplicationContext 在启动时会预先实例化所有的 Bean,因此启动时间相对较长,但是在应用程序运行时,获取 Bean 的速度更快。
③ 除了这两种常见的 IOC 容器,Spring 还提供了其他类型的 IOC 容器,如 WebApplicationContext、AnnotationConfigApplicationContext 等,它们都是 ApplicationContext 的子类,提供了不同的功能和使用场景。

13. Spring ApplicationContext 通常的实现是什么?

ApplicationContext 通常的实现是 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext。

在这里插入图片描述

① ClassPathXmlApplicationContext:从类路径下加载 XML 配置文件的 ApplicationContext;

② FileSystemXmlApplicationContext:从文件系统中加载 XML 配置文件的 ApplicationContext ;

③ AnnotationConfigApplicationContext:加载注解配置类的 ApplicationContext;

12. Spring BeanFactory 和 ApplicationContext有什么区别?

BeanFactory 和 ApplicationContext 都是 Spring 容器,它们的主要区别如下:

在这里插入图片描述

① BeanFactory 是 Spring 框架最基本的容器,提供了最基本的 IoC 和 DI 功能,它的主要作用是管理 Bean 对象及其依赖关系。ApplicationContext 是 BeanFactory 的子接口,提供了更多的功能,如国际化、事件传播、资源加载等。

② BeanFactory 是延迟初始化的,即只有在第一次使用 Bean 对象时才会进行初始化。ApplicationContext 是预初始化的,即在容器启动时就会进行初始化。

③ BeanFactory 是轻量级的容器,只提供了基本的 IoC 和 DI 功能,适用于简单的应用场景。ApplicationContext 是重量级的容器,提供了更多的功能,适用于复杂的应用场景。

④ BeanFactory 可以通过编程方式进行配置,也可以通过 XML 配置文件进行配置。ApplicationContext 可以通过编程方式、XML 配置文件、注解等多种方式进行配置。

⑤ BeanFactory 是单例模式的,即整个应用只有一个 BeanFactory 实例。ApplicationContext 可以是单例模式的,也可以是多例模式的,即可以创建多个 ApplicationContext 实例。

总的来说,BeanFactory 和 ApplicationContext 都是 Spring 容器,它们的主要区别在于功能和初始化方式。BeanFactory 提供了最基本的 IoC 和 DI 功能,适用于简单的应用场景;ApplicationContext 提供了更多的功能,适用于复杂的应用场景。开发者可以根据实际情况选择最合适的容器。

14. Spring 容器是如何设计的?

Spring 容器的设计主要分为两个层次:BeanFactory 和 ApplicationContext。

① BeanFactory 是 Spring 容器的基础,提供了最基本的 IoC 和 DI 功能,它的主要作用是管理 Bean 对象及其依赖关系。BeanFactory 是延迟初始化的,即只有在第一次使用 Bean 对象时才会进行初始化。BeanFactory 是轻量级的容器,只提供了基本的 IoC 和 DI 功能,适用于简单的应用场景。

② ApplicationContext 是 BeanFactory 的子接口,提供了更多的功能,如国际化、事件传播、资源加载等。ApplicationContext 是预初始化的,即在容器启动时就会进行初始化。ApplicationContext 是重量级的容器,提供了更多的功能,适用于复杂的应用场景。

③ BeanFactory 和 ApplicationContext 的关系是继承关系,ApplicationContext 继承了 BeanFactory 的所有功能,并在此基础上提供了更多的功能。ApplicationContext 可以通过编程方式、XML 配置文件、注解等多种方式进行配置,可以是单例模式的,也可以是多例模式的,即可以创建多个 ApplicationContext 实例。

④ 在 Spring 容器的设计中,BeanFactory 和 ApplicationContext 的关系是一种典型的模板方法模式。BeanFactory 定义了容器的基本行为,ApplicationContext 在此基础上提供了更多的功能,同时也可以通过扩展 BeanFactory 接口来实现自定义的容器行为。

总的来说,Spring 容器的设计是基于 BeanFactory 和 ApplicationContext 两个层次的,BeanFactory 提供了最基本的 IoC 和 DI 功能,ApplicationContext 在此基础上提供了更多的功能,两者之间是继承关系。开发者可以根据实际情况选择最合适的容器。

15. Spring 容器如何配置元数据?

Spring 容器可以通过多种方式来提供配置元数据,包括:

① 基于 XML 的配置方式:通过编写 XML 配置文件来定义 Bean 对象及其依赖关系。

② 基于注解的配置方式:通过在 Bean 对象的类或属性上添加注解来定义 Bean 对象及其依赖关系。常用的注解包括 @Component、@Service、@Repository、@Autowired 等。

③ 基于 Java 的配置方式:通过编写 Java 代码来定义 Bean 对象及其依赖关系。常用的类包括 @Configuration、@Bean、@Import 等。

总的来说,Spring 容器可以通过基于 XML、注解、Java等多种方式来提供配置元数据,开发者可以根据实际情况选择最合适的方式。

16. Spring BeanFactory 容器如何使用?

BeanFactory是Spring框架中最基本的IoC容器,它负责创建、管理和装配Bean对象。

① 创建BeanFactory对象

// 创建一个BeanFactory容器对象
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

// 创建一个读取器(读取XML文件)
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions("beans.xml");

② 配置Bean对象:在配置文件中定义Bean对象的配置信息,包括Bean的类名、属性值等。

public class UserServiceImpl implements UserService {
 private UserDao userDao;
 
 // setter方法注入:通过setter方法的参数列表,通知BeanFactory容器此对象所需的依赖对象
 // BeanFactory 容器会调用此方法,将对象的依赖对象注入
 public void setUserDao(UserDao userDao) {
     this.userDao = userDao;
 }
 
 public void getUserById(int id) {}
}
<bean id="userService" class="com.example.UserService">
 <property name="userDao" ref="userDao"/>
</bean>

<bean id="userDao" class="com.example.UserDaoImpl"/>

③ 获取Bean对象:通过BeanFactory的getBean方法来获取Bean对象,可以根据Bean的ID或类名来获取Bean对象。

UserService userService = (UserService) beanFactory.getBean("userService");

④ 使用Bean对象:获取到Bean对象后,就可以使用它的方法来完成具体的业务逻辑。

User user = userService.getUserById(1);

总之,使用 BeanFactory 的步骤包括创建 BeanFactory 对象、配置 Bean 对象、获取 Bean 对象和使用 Bean 对象。BeanFactory 是 Spring 框架中最基本的 IoC 容器,可以帮助开发人员实现对象的创建、管理和装配。

17. Spring ApplicationContext 容器如何使用?

ApplicationContext是Spring框架中的一个高级IoC容器,它继承了BeanFactory接口,并提供了更多的功能,如国际化、事件传播、资源加载等。

① 创建ApplicationContext容器:可以通过ClassPathXmlApplicationContext或FileSystemXmlApplicationContext等类来创建ApplicationContext容器,这些类都是ApplicationContext的实现类。

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

② 配置Bean对象:在配置文件中定义Bean对象的配置信息,包括Bean的类名、属性值等。

<bean id="userService" class="com.example.UserService">
 <property name="userDao" ref="userDao"/>
</bean>

<bean id="userDao" class="com.example.UserDaoImpl"/>

③ 获取Bean对象:通过ApplicationContext容器的getBean方法来获取Bean对象,可以根据Bean的ID或类名来获取Bean对象。

UserService userService = (UserService) context.getBean("userService");

④ 使用Bean对象:获取到Bean对象后,就可以使用它的方法来完成具体的业务逻辑。

User user = userService.getUserById(1);

总之,使用ApplicationContext容器的步骤包括创建ApplicationContext容器、配置Bean对象、获取Bean对象和使用Bean对象。ApplicationContext容器是Spring框架中的一个高级IoC容器,提供了更多的功能,如国际化、事件传播、资源加载等。

18. Spring BeanFactory 容器源码?

BeanFactory是Spring 中最基本的IoC容器,它负责创建、管理和装配Bean对象。

① BeanFactory接口定义了获取Bean对象的方法,包括getBean(String name)、getBean(String name, Class<T> requiredType)、getBean(Class<T> requiredType) 等。

public interface BeanFactory {
 Object getBean(String name) throws BeansException;
 <T> T getBean(String name, Class<T> requiredType) throws BeansException;
 <T> T getBean(Class<T> requiredType) throws BeansException;
 boolean containsBean(String name);
 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
 boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
 Class<?> getType(String name) throws NoSuchBeanDefinitionException;
}

② DefaultListableBeanFactory 是 BeanFactory 接口的实现类。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {
 // ...
}

③ DefaultListableBeanFactory的主要作用是管理BeanDefinition对象,它通过BeanDefinitionReader将配置文件中的BeanDefinition对象加载到BeanFactory中。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {
 // ...
 public int registerBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
     BeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
     return reader.loadBeanDefinitions(resource);
 }
 // ...
}

④ DefaultListableBeanFactory的getBean方法实现了Bean对象的创建和依赖注入,它通过BeanDefinition对象来创建Bean对象,并将依赖的Bean对象注入到目标Bean对象中。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {
 // ...
 @Override
 public Object getBean(String name) throws BeansException {
     return doGetBean(name, null, null, false);
 }

 @Override
 public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
     return doGetBean(name, requiredType, null, false);
 }

 @Override
 public <T> T getBean(Class<T> requiredType) throws BeansException {
     return doGetBean(null, requiredType, null, false);
 }

 protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
     // ...
     BeanDefinition bd = mbd;
     // ...
     Object bean = createBean(beanName, bd, args);
     // ...
     return (T) bean;
 }
 // ...
}

总之,BeanFactory是Spring框架中最基本的IoC容器,它通过BeanDefinition对象来管理Bean对象,实现了对象的创建、管理和装配。DefaultListableBeanFactory是BeanFactory的默认实现类,它实现了BeanFactory接口,并通过BeanDefinitionReader将配置文件中的BeanDefinition对象加载到BeanFactory中。

19. Spring ApplicationContext 源码?

① ApplicationContext 接口继承自 BeanFactory 接口并实现了更多的方法

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
 String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
 void publishEvent(ApplicationEvent event);
 // ...
}

② AbstractApplicationContext是ApplicationContext的抽象,实现了ConfigurableApplicationContext ,继承了 DefaultResourceLoader。

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
 // ...
}

③ AbstractApplicationContext是ApplicationContext的抽象实现类,它通过BeanDefinitionReader将配置文件中的BeanDefinition对象加载到BeanFactory中,并发布ApplicationContext事件。

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
 // ...
 protected void refreshBeanFactory() throws BeansException {
     if (hasBeanFactory()) {
         destroyBeans();
         closeBeanFactory();
     }
     try {
         DefaultListableBeanFactory beanFactory = createBeanFactory();
         beanFactory.setSerializationId(getId());
         customizeBeanFactory(beanFactory);
         loadBeanDefinitions(beanFactory);
         synchronized (this.beanFactoryMonitor) {
             this.beanFactory = beanFactory;
         }
     }
     // ...
 }

 protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
     ApplicationEvent applicationEvent;
     if (event instanceof ApplicationEvent) {
         applicationEvent = (ApplicationEvent) event;
     }
     else {
         applicationEvent = new PayloadApplicationEvent<>(this, event);
         if (eventType == null) {
             eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
         }
     }
     if (logger.isTraceEnabled()) {
         logger.trace("Publishing event in " + getDisplayName() + ": " + applicationEvent);
     }
     getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
     if (this.parent != null) {
         this.parent.publishEvent(event, eventType);
     }
 }
 // ...
}

④ AbstractApplicationContext的getBean方法实现了Bean对象的创建和依赖注入,它通过BeanDefinition对象来创建Bean对象,并将依赖的Bean对象注入到目标Bean对象中。

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
 // ...
 @Override
 public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
     return getBeanFactory().getBean(name, requiredType);
 }

 @Override
 public Object getBean(String name) throws BeansException {
     return getBeanFactory().getBean(name);
 }

 @Override
 public <T> T getBean(Class<T> requiredType) throws BeansException {
     return getBeanFactory().getBean(requiredType);
 }
 // ...
}

总之,ApplicationContext是Spring框架中的一个高级IoC容器,它继承了BeanFactory接口,并提供了更多的功能,如国际化、事件传播、资源加载等。AbstractApplicationContext是ApplicationContext的抽象实现类,它通过BeanDefinitionReader将配置文件中的BeanDefinition对象加载到BeanFactory中,并发布ApplicationContext事件。在获取Bean对象时,AbstractApplicationContext会根据BeanDefinition对象来创建Bean对象,并将依赖的Bean对象注入到目标Bean对象中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/404762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式系统实验——【玄武F103开发板】按key1熄灭两个LED灯、松开恢复点亮

这里写目录标题一、任务目标&#xff08;一&#xff09;分析二、设计思路&#xff08;一&#xff09;开启KEY1对应的GPIOx时钟1.找到KEY1&#xff08;PE3&#xff09;所在的GPIOx端口2.开启GPIOE端口时钟3.清空PE3的端口位4.设置PE3的端口位为输出模式的上拉模式5.一个易错点&a…

二分——力扣篇

二分——力扣篇搜索旋转排序数组搜索旋转排序数组II寻找旋转排序数组中的最小值寻找旋转排序数组中的最小值II搜索旋转排序数组 定理一&#xff1a;只有在顺序区间内才可以通过区间两端的数值判断target是否在其中。 定理二&#xff1a;判断顺序区间还是乱序区间&#xff0c;只…

案例学习20之内存长期占用导致系统缓慢

前言&#xff1a; 发现问题&#xff0c;解决问题&#xff0c;是贯穿整个项目开发过程的事情&#xff0c;能够处理更多的问题&#xff0c;随着经验的丰富&#xff0c;提前预知更多的问题&#xff0c;让问题不出现是最好的解决问题方式。 问题背景&#xff1a; 项目运行过程中出现…

基于redis实现点赞数,点击数,排行榜

使用场景 对于某些视频或者文章有点赞数和点击数, 通过这些数据就可以进行排行榜的功能了 使用异步队列 redis的集合 A.php //点击数 $redis->zIncrBy(click.:.date(Ymd),1,$videoId); //点赞数 $redis->zIncrBy(love.:.$videoId,1,$$user); //获取当前video的播放数…

PMP项目管理项目范围管理

目录1 项目范围管理概述2 规划范围管理3 收集需求4 定义范围5 创建 WBS6 确认范围7 控制范围1 项目范围管理概述 项目范围管理包括确保项目做且只做所需的全部工作&#xff0c;以成功完成项目的各 个过程。管理项目范围主要在于定义和控制哪些工作应在项目内&#xff0c;哪些工…

界面原型设计

引用锤子科技视觉设计总监——罗子雄在重庆TEDx活动上说的一小段话: 每当我们看到一些美妙的设计的时候,很多人心里面会有一种冲动,这种冲动会让你们想去创造一些新的东西,创造一些美妙的事物。 我们常说用户体验用户体验,用户使用你的软件,第一个会接触的是什么?没错,…

读WiscKey: Separating Keys from Values in SSD-conscious Storage

在我看来本论文的主要贡献在于相对减轻了传统LSM compact所带来的写放大问题。其核心设计在于使key、value分离以及gc只保持有效数据 key、value分离 作者对于key、value分离策略的观察主要来自于排序是以往LSM性能消耗最大的地方&#xff0c;但是真正影响排序的与占用大储存…

推荐五款宝藏软件,身为宝藏男孩和宝藏女孩的你,不试一下吗?

今天带来五款宝藏软件&#xff0c;身为宝藏男孩和宝藏女孩的你们&#xff0c;不试一下吗&#xff1f; 1.EPUB阅读器——Starrea Starrea 是一款Windows平台的EPUB电子书阅读器&#xff0c;它虽然只支持一个平台&#xff0c;但是提供了很多额外的功能&#xff0c;其中包括 文…

Java之线程总结一

Java之线程总结一 线程实现方式 官方文档说的是实现线程的方式有两种&#xff1b;本质上只有一种&#xff0c;就是构造Thread类&#xff0c;而实现线程执行单元的方式有两种&#xff1a; 继承Thread类&#xff0c;重写run方法&#xff1b;实现Runnable接口的run方法&#xf…

RHEL8.5解决libgdiplus绘图问题

最近有客户服务器使用RHEL8.5了。由于之前测试和编译的dotnetcore在Linux下绘图包libgdiplus都是在centos7.6编译的。把CentOS7.6编译的二进制程序之前试CentOS7.9使用没问题&#xff0c;然后RHEL8.5无法正常绘图。由于之前搞统信那些系统发现了包得在对应系统源码编译才行。所…

Java web基于SSM的停车场管理系统的设计与实现

1&#xff0c;项目介绍 Java web基于SSM的停车场管理系统拥有三种角色&#xff0c;分别为用户&#xff0c;管理员&#xff0c;超级管理员。 停车位管理&#xff08;管理员&#xff0c;超级管理员&#xff09;停车卡管理&#xff08;用户&#xff0c;管理员&#xff0c;超级管…

Vue3视频播放器组件Vue3-video-play入门教程

Vue3-video-play适用于 Vue3 的 hls.js 播放器组件 | 并且支持MP4/WebM/Ogg格式。 1、支持快捷键操作 2、支持倍速播放设置 3、支持镜像画面设置 4、支持关灯模式设置 5、支持画中画模式播放 6、支持全屏/网页全屏播放 7、支持从固定时间开始播放 8、支持移动端&#xff0c;移动…

pyqt5环境搭建

1、打开Terminal ,用命令pip install pyqt5-tools 或者 pip install pyqt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple安装PyQt5安装成功后就可看到PyQt5版本2、同上方法&#xff0c;继续安装pyqt5-tools扩展工具&#xff0c;里面包括了QtDesigner等很好用的工具。3、…

二进制哈希码快速搜索:Multi-Index Hashing

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 哈希方法通常包含两个部分&#xff1a; 【编码】将元素通过「data-dependent」或「data-independent」的方式映射为二进制…

C变量区域

C语言中有五大内存分区&#xff0c;分别是栈区、堆区、全局区/静态区、常量区和代码区。1.栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值、局部变量的值等。当调用函数的时候函数中定义的变量会被加到栈中&#xff0c;当函数离开的时候&#xff0c;被添加…

HTML看这一篇就够啦,HTML基础大全,可用于快速回顾知识,面试首选

HTML 1 基础 1.1 DOCTYPE <!DOCTYPE> 文档类型声明&#xff0c;作用就是告诉浏览器使用哪种HTML版本来显示网页。 <!DOCTYPE html> 这句代码的意思是: 当前页面采取的是 HTML5 版本来显示网页. 注意: 声明位于文档中的最前面的位置&#xff0c;处于 标签之前。 …

互联网新理念,对于WEB 3.0 你怎么看?

WEB 3.0 这个名词走进大众视野已经有一段时间了&#xff0c;也曾在各个圈子里火热一时&#xff0c;至今各大互联网企业任旧在 WEB 3.0 上不断探索。但关于 WEB 3.0 是什么这个问题&#xff0c;其实大部分人都没有一个比较明确的认知&#xff0c;包括区块链和元宇宙等相关行业的…

【设计模式】备忘录模式和迭代器模式

备忘录模式和迭代器模式备忘录模式代码示例迭代器模式代码示例使用迭代器遍历集合的同时不能删除/增加元素总结备忘录模式 备忘录模式&#xff0c;也叫快照&#xff08;Snapshot&#xff09;模式。 在 GoF的《设计模式》⼀书中&#xff0c;备忘录模式是这么定义的&#xff1a;…

【Spring6】面向切面:AOP

5.1、场景模拟 搭建子模块&#xff1a;spring6-aop 5.1.1、声明接口 声明计算器接口Calculator&#xff0c;包含加减乘除的抽象方法 public interface Calculator {int add(int i, int j);int sub(int i, int j);int mul(int i, int j);int div(int i, int j);}5.1.2、创建…

计算机视觉与深度学习 | Visual ChatGPT:微软开源视觉(图文)聊天系统——图像生成、迁移学习、边缘检测、颜色渲染等多功能(附代码下载链接)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== Visual ChatGPT: Talking, Drawing and Editing with V