文章目录
- 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对象中。