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 和依赖注入是什么?02. Spring IoC 的优点和缺点分别是什么?03. Spring IoC 有什么作用和功能?04. Spring 依赖注入的方式?05. Spring 构造器注入和 setter 方法注入的区别?06. Spring 依赖注入…...

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

【H2实践】之 SpringBoot 与 H2 数据交互
一、目标 本文是【H2实践】之认识 H2,【H2实践】之 SpringBoot 整合的后续。前文分别介绍了 H2 及其简单使用,并完成了 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…...

建立自己的博客(记录-不推荐)
环境安装: w10系统安装 第一步:安装git Git 官网: https://git-scm.com/ 第二步:安装Node.js Node.js官网:https://nodejs.org/zh-cn/ 使用cmd检测: node -v 第三步:安装Hexo Hexo官网:htt…...

hashmap存储方式 hash碰撞及其解决方式
1.Map的存储特点 在Map这个结构中,数据是以键值对(key-value)的形式进行存储的,每一个存储进map的数据都是一一对应的。 创建一个Map结构可以使用new HashMap()以及new TreeMap()两种方式,两者之间的区别是:…...

Amazon GuardDuty 的新增功能 – Amazon EBS 卷的恶意软件检测
亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术,观点,和项目,并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏…...
YOLOv7 pytorch
yolov7主干部分结构图:yolov7主干 yolov7数据集处理代码:yolov7数据集处理代码 yolov7训练参数解释:yolov7训练参数【与本文代码有区别】 yolov7训练代码详解:yolov7训练代码详解 目录 训练自己的训练集 训练自己的训练集 此…...

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

IO多路复用--[select | poll | epoll | Reactor]
因为在简历上写了netty的项目,因此还是将网络底层的那点东西搞清楚。 首先希望明确的是,BIO、NIO、IO多路复用这是不同的东西, 我会在本文中详细讲出来。 本文参考资料: JAVA IO模型 IO多路复用 select poll epoll介绍 从BIO到epo…...
pod的requests、limits解读、LimitRange资源配额、Qos服务质量等级、资源配额管理 Resource Quotas
前言 环境: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语言基础(一):注释、变量 R语言基础(二):常用函数 R语言基础(三):运算 R语言基础(四):数据类型 R语言基础(五):流程控制语句 7. 函数 函数是一组完成特定功能的语句。 7.1 内置函数 R语言系统中提供许多内置函数&…...
[C++] 简单序列化
前言 序列化(Serialization) 是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。 使用 序列化 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滤波第二个版本简介 上一篇文章,我们介绍了UKF滤波公式及其MATLAB代码。在做视觉测量的过程中,基于OpenCV的开发包比较多,因此我们将UKF的MATLAB代码转到python中&a…...

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

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

每天5分钟玩转机器学习算法:逆向概率的问题是什么?贝叶斯公式是如何解决的?
本文重点 前面我们已经知道了贝叶斯公式,以及贝叶斯公式在机器学习中的应用,那么贝叶斯公式究竟解决了一个什么样的问题呢?贝叶斯是为了解决逆向概率的问题。 正向的概率和逆向的概率 正向概率:假设袋子里面有N个白球,有M个黑球,你伸手一摸,那么问题就是你摸出黑球的概…...
游戏闲聊之游戏是怎么赚钱的
其实一般情况下不太爱写这种文章,简单说就一点,这个行业的人我惹不起。 1、外挂 所谓外挂,是指通过技术手段,提供辅助游戏的工具,方便玩家获得一些额外的能力; 这事我特意咨询过律师,外挂分两…...

Redis高频面试题汇总(下)
目录 1.Redis中什么是Big Key(大key) 2.Big Key会导致什么问题 3.如何发现 bigkey? 4.为什么redis生产环境慎用keys *命令 5.如何处理大量 key 集中过期问题 6.使用批量操作减少网络传输 7.缓存穿透 8.缓存击穿 9.缓存雪崩 10.缓存污染(或满了…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...