当前位置: 首页 > news >正文

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

文章目录

      • 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 {// ...@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);}@Overridepublic <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 {// ...@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {return getBeanFactory().getBean(name, requiredType);}@Overridepublic Object getBean(String name) throws BeansException {return getBeanFactory().getBean(name);}@Overridepublic <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对象中。

相关文章:

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

文章目录01. Spring IoC 和依赖注入是什么&#xff1f;02. Spring IoC 的优点和缺点分别是什么&#xff1f;03. Spring IoC 有什么作用和功能&#xff1f;04. Spring 依赖注入的方式&#xff1f;05. Spring 构造器注入和 setter 方法注入的区别&#xff1f;06. Spring 依赖注入…...

顺序表来喏!!!

前言&#xff1a;还记得前面的文章&#xff1a;《通讯录的实现》吗&#xff1f;通讯录的完成就借助了顺序表这种数据结构&#xff01;&#xff01;&#xff01;那么今天我们就来介绍我们的顺序表介绍顺序表前&#xff0c;我们来了解一下线性表的概念线性表&#xff1a;线性表&a…...

【H2实践】之 SpringBoot 与 H2 数据交互

一、目标 本文是【H2实践】之认识 H2&#xff0c;【H2实践】之 SpringBoot 整合的后续。前文分别介绍了 H2 及其简单使用&#xff0c;并完成了 H2 与 SpringBoot 的整合。本文将紧接 【H2实践】之 SpringBoot 整合 探索实用 SpringBoot 结合 JPA 通过 web 接口操作 H2 数据库的…...

LeetCode 424. Longest Repeating Character Replacement

LeetCode 424. Longest Repeating Character Replacement https://leetcode.com/problems/longest-repeating-character-replacement/ 题目描述 You are given a string s and an integer k. You can choose any character of the string and change it to any other upperc…...

建立自己的博客(记录-不推荐)

环境安装&#xff1a; w10系统安装 第一步&#xff1a;安装git Git 官网: https://git-scm.com/ 第二步&#xff1a;安装Node.js Node.js官网&#xff1a;https://nodejs.org/zh-cn/ 使用cmd检测&#xff1a; node -v 第三步&#xff1a;安装Hexo Hexo官网&#xff1a;htt…...

hashmap存储方式 hash碰撞及其解决方式

1.Map的存储特点 在Map这个结构中&#xff0c;数据是以键值对&#xff08;key-value&#xff09;的形式进行存储的&#xff0c;每一个存储进map的数据都是一一对应的。 创建一个Map结构可以使用new HashMap()以及new TreeMap()两种方式&#xff0c;两者之间的区别是&#xff1a…...

Amazon GuardDuty 的新增功能 – Amazon EBS 卷的恶意软件检测

亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术&#xff0c;观点&#xff0c;和项目&#xff0c;并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏…...

YOLOv7 pytorch

yolov7主干部分结构图&#xff1a;yolov7主干 yolov7数据集处理代码&#xff1a;yolov7数据集处理代码 yolov7训练参数解释&#xff1a;yolov7训练参数【与本文代码有区别】 yolov7训练代码详解&#xff1a;yolov7训练代码详解 目录 训练自己的训练集 训练自己的训练集 此…...

JDK自带JVM分析工具

一、JDK自带工具盘点&#xff1a; jstat&#xff1a;性能分析-查看gc情况&#xff1b; jmap&#xff1a;内存分析-堆信息&#xff1b; jstack&#xff1a;线程分析-栈信息&#xff1b; jinfo&#xff1a;参数查看及配置&#xff1b; jstatd&#xff1a;启动jvm监控服务。它…...

IO多路复用--[select | poll | epoll | Reactor]

因为在简历上写了netty的项目&#xff0c;因此还是将网络底层的那点东西搞清楚。 首先希望明确的是&#xff0c;BIO、NIO、IO多路复用这是不同的东西&#xff0c; 我会在本文中详细讲出来。 本文参考资料&#xff1a; JAVA IO模型 IO多路复用 select poll epoll介绍 从BIO到epo…...

pod的requests、limits解读、LimitRange资源配额、Qos服务质量等级、资源配额管理 Resource Quotas

前言 环境&#xff1a;k8s-v1.22.17 docker-20.10.9 centos-7.9 目录前言什么是可计算资源CPU、Memory计量单位pod资源请求、限额方式pod定义requests、limits查看节点资源情况pod使用request、limits示例LimitRange限制命名空间下的pod的资源配额Qos服务质量等级资源配额管理…...

R语言基础(六):函数

R语言基础(一)&#xff1a;注释、变量 R语言基础(二)&#xff1a;常用函数 R语言基础(三)&#xff1a;运算 R语言基础(四)&#xff1a;数据类型 R语言基础(五)&#xff1a;流程控制语句 7. 函数 函数是一组完成特定功能的语句。 7.1 内置函数 R语言系统中提供许多内置函数&…...

[C++] 简单序列化

前言 序列化(Serialization) 是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间&#xff0c;对象将其当前状态写入到临时或持久性存储区。以后&#xff0c;可以通过从存储区中读取或反序列化对象的状态&#xff0c;重新创建该对象。 使用 序列化 std::array&…...

Autosar Configuration(十三)SomeIP之配置TCP/IP

本系列教程是根据实际项目开发中总结的经验所得,如发现有不对的地方,还请指正。 目录Autosar Configuration(一)Davinci Developer-工具介绍 Autosar Configuration(二)Davinci Developer-SWC配置 Autosar Configuration(三) Security之Crypto配置 Autosar Configurat…...

滤波算法 | 无迹卡尔曼滤波(UKF)算法及其Python实现

文章目录简介UKF滤波1. 概述和流程2. Python代码第一个版本a. KF滤波b. UKF滤波第二个版本简介 上一篇文章&#xff0c;我们介绍了UKF滤波公式及其MATLAB代码。在做视觉测量的过程中&#xff0c;基于OpenCV的开发包比较多&#xff0c;因此我们将UKF的MATLAB代码转到python中&a…...

IMU 积分的误差状态空间方程推导

文章目录0. 前言1. 离散时间的IMU运动学方程2. 状态变量定义3. 补充公式4. IMU误差状态空间方程推导4.1. 旋转误差 δr^i1\delta\hat{\mathbf{r}}_{i1}δr^i1​4.2. 速度误差 δv^i1\delta\hat{\mathbf{v}}_{i1}δv^i1​4.3. 平移误差 δpi1\delta \mathbf{p}_{i1}δpi1​4.4. …...

VirtualBox的克隆与复制

快照太多&#xff0c;想整合成1个文件怎么办&#xff1f; 最近&#xff0c;我就遇到一个问题。快照太多了。比较占用空间怎么办&#xff1f; 错误做法 一开始&#xff0c;我是这么操作的&#xff0c;选中某个快照&#xff0c;然后选择删除…然后我登录虚拟机后&#xff0c;发…...

每天5分钟玩转机器学习算法:逆向概率的问题是什么?贝叶斯公式是如何解决的?

本文重点 前面我们已经知道了贝叶斯公式,以及贝叶斯公式在机器学习中的应用,那么贝叶斯公式究竟解决了一个什么样的问题呢?贝叶斯是为了解决逆向概率的问题。 正向的概率和逆向的概率 正向概率:假设袋子里面有N个白球,有M个黑球,你伸手一摸,那么问题就是你摸出黑球的概…...

游戏闲聊之游戏是怎么赚钱的

其实一般情况下不太爱写这种文章&#xff0c;简单说就一点&#xff0c;这个行业的人我惹不起。 1、外挂 所谓外挂&#xff0c;是指通过技术手段&#xff0c;提供辅助游戏的工具&#xff0c;方便玩家获得一些额外的能力&#xff1b; 这事我特意咨询过律师&#xff0c;外挂分两…...

Redis高频面试题汇总(下)

目录 1.Redis中什么是Big Key(大key) 2.Big Key会导致什么问题 3.如何发现 bigkey&#xff1f; 4.为什么redis生产环境慎用keys *命令 5.如何处理大量 key 集中过期问题 6.使用批量操作减少网络传输 7.缓存穿透 8.缓存击穿 9.缓存雪崩 10.缓存污染&#xff08;或满了…...

Windows修改Docker安装目录修改Docker镜像目录,镜像默认存储位置存放到其它盘

Windows安装Docker&#xff0c;默认是安装在C盘&#xff0c;下载镜像后会占用大量空间&#xff0c;这时需要调整镜像目录&#xff1b;场景&#xff1a;不想连服务器或者没有服务器&#xff0c;想在本地调试服务&#xff0c;该需求就非常重要。基于WSL2安装docker后&#xff0c;…...

376. 摆动序列——【Leetcode每日刷题】

376. 摆动序列 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如&#xff0c; [1, 7, 4, 9, 2, 5] 是一个…...

mgre实验

实验思路 1、首先根据拓扑结构合理分配IP地址&#xff0c;并对各个路由器的IP地址和R5环回接口的IP地址进行配置。 2、让私网中的边界路由器对ISP路由器做缺省路由。 3、根据实验要求&#xff0c;对需要配置不同类型认证的路由器进行认证配置&#xff0c;和需要不同封装的协议…...

一文彻底了解Zookeeper(介绍篇)

zookeeper 是什么&#xff1f; zookeeper是一个分布式协作框架&#xff0c;提供高可用&#xff0c;高性能&#xff0c;强一致等特性 zookeeper 有哪些应用场景&#xff1f; 分布式锁&#xff1a;分布式锁是指在分布式环境中&#xff0c;多个进程或线程需要互斥地访问某个共享…...

1. ELK Stack 理论篇之什么是ELK Stack?

ELK Stack 理论篇之什么是ELK Stack?1.1 什么是 ELK Stack&#xff1f;1.2 ELK Stack的发展史1.2.1 Elasticsearch1.2.2 引入 Logstash 和 Kibana&#xff0c;产品更强大1.2.3 社区越来越壮大&#xff0c;用例越来越丰富1.2.4 然后我们向 ELK 中加入了 Beats1.2.5 那么&#x…...

两道有关链表的练习

目录 一、分割链表 二、奇偶链表 一、分割链表 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。 示例 1&#xff1a; 输…...

Python uiautomator2安卓自动化测试

一、前言 uiautomator2是Python对Android设备进行UI自动化的库&#xff0c;支持USB和WIFI链接&#xff0c;可以实现获取屏幕上任意一个APP的任意一个控件属性&#xff0c;并对其进行任意操作。 重点是它可以实现安卓自动化采集&#xff0c;甚至是群控采集&#xff0c;且安装和…...

Leetcode. 160相交链表

文章目录指针解法指针解法 核心思路 &#xff1a; 先 分别求两个链表的长度 然后长的链表先走 差距步&#xff08;长-短&#xff09; 最后长链表和短链表同时走 &#xff0c;第一地址相同的就是交点 &#xff0c;注意一定是地址相同 不可能出现上图这种情况 &#xff0c;因为C1…...

MDPs —— 马尔可夫决策定义与算法

文章目录MDPs 定义——由实例开始时序决策问题给游戏增点乐子*为什么要有折扣游戏的解——原则所以&#xff0c;什么是 MDPs&#xff1f;MDPs 的基本原理、表示光环原理效用的求解是反向传播的原则不变条件MDPs 的表示MDPs 求解效用迭代法缺点原则迭代法MDPs 定义——由实例开始…...

【C++】图

本文包含了图的基本概念 1.相关概念 1.1 无/有向 无向图&#xff1a;每一个顶点之间的连线没有方向 有向图&#xff1a;连线有方向&#xff08;类似离散数学的二元关系 <A,B>代表从A到B的边&#xff0c;有方向&#xff09; <A,B>中A为始点&#xff0c;B为终点在…...

设计网网站/外贸网站建站和推广

1 集合 集合是一个无序的&#xff0c;不重复的数据组合&#xff0c;它的主要作用如下&#xff1a; 去重&#xff0c;把一个列表变成集合&#xff0c;就自动去重了关系测试&#xff0c;测试两组数据之前的交集、差集、并集等关系创建集合 a {3, 5, 9, 9, 10} print(a) b ([1, …...

免费做简历网站有哪些/长沙今日头条新闻

Python OpenCV 365 天学习计划&#xff0c;与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 46 篇。 该系列文章导航参考&#xff1a;https://blog.csdn.net/hihell/category_10688961.html Python OpenCV基础知识铺垫Sobel 算子Scharr 算子laplacian 算子橡皮擦的小节基础…...

wordpress自定义字段/视频号推广方法

ArchLinux Gnome3 Wayland wine-wechat微信多开方法由于市面上使用deepin-wine-wechat的好多&#xff0c;但是deepin-wine-wechat启动慢并且有黑框&#xff0c;于是我尝试了archlinuxcn中的wine-for-wechat和wine-wechat组合使用&#xff0c;最为明显的是没有黑框了&#xff0c…...

建筑设计师专业网站/百度引流怎么推广

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼该程序用于实现linux系统中wc命令的最简单模式wc 命令用于统计文件中字符信息。[xxlocalhost 1.5]$ wc 01.c 02.c 03.c15 23 131 01.c13 18 127 02.c14 20 128 03.c42 61 386 总用量使用c语言写出这种小程序。/** Name: count.c* T…...

高端品牌网站建设公司/搜索引擎营销与seo优化

Competition Add : https://www.kaggle.com/c/digit-recognizer 此题目已经把每个图片向量化了。下载到的data里包含三个文件&#xff1a; 数据文件train.csv和test.csv包含从0到9的手绘数字的灰度图像。 每个图像的高度为28个像素&#xff0c;宽度为28个像素&#xff0c;总共…...

wordpress 安装根目录/北仑seo排名优化技术

OSI: open system interconnection 开放式系统互联参考模型 OSI 和TCP/IP 的对应关系和协议 概述 OSI模型各层的基本作用&#xff1a; OSI对应tcp/ip和五层协议 OSI TCP/IP对应网络协议 详解OSI七层网络模型 物理层 数据链路层 网络层 传输层 应用层 最后一张图&…...